我如何使返回表的列等于另一个表的行,像这样?

时间:2016-03-10 00:31:58

标签: sql sql-server tsql stored-procedures database-design

我有3张表,比如

         Dudes
==========================
 id |    name   
==========================
  1 |  "Marshal Mathers"
--------------------------
  2 |  "Limp Biscuit"
--------------------------


        Questions 
===========================
 id |       qtext
===========================
 1  | "What's up, dog?"
---------------------------
 2  | "C# or C++?"
---------------------------

          Answers
=======================================================
 id |  dude_id  | question_id |       atext
=======================================================
  1 |      1       |       1     |    "Nothing much"
-------------------------------------------------------
  2 |      2       |       1     |     "Oh, you know"
-------------------------------------------------------
  3 |      1       |       2     |         "C++"
-------------------------------------------------------- 

我对Make-A-Wish Foundation(Stack Overflow)的愿望是针对一个在该示例中返回的sproc

===========================================================
          name         |  What's up, dog?  |  C# or C++?   
===========================================================
    "Marshal Mathers"  |   "Nothing much"  |    "C++"
-----------------------------------------------------------
     "Limp Biscuit"    |   "Oh, you know"  |     NULL
------------------------------------------------------------

这是可能的,如果可以的话,它会怎么做?

2 个答案:

答案 0 :(得分:1)

假设我正确理解了您的问题,您可以conditional aggregation使用pivot outer join select d.id, d.name, max(case when q.id = 1 then q.qtext end) whats_up_dog, max(case when q.id = 2 then q.qtext end) c_sharp_plus from dudes d left join answers a on d.id = a.partner_id left join questions q on q.id = a.question_id group by d.id, d.name 结果:

var data = [{
    id: "Calligraphy",
    category: "artsAndCrafts",
    categoryName: "Arts & Crafts",
    place: "indoor",
    activity: "light",
    difficulty: "medium",
    link:"tennis.html",
    description:"Knitting is great"
}, {
    id: "Cross-stitching",
    category: "artsAndCrafts",
    categoryName: "Arts & Crafts",
    place: "indoor",
    activity: "light",
    difficulty: "easy",
    link:"knitting.html",
    description:"Knitting is great"
}, {
    id: "Gardening",
    category: "artsAndCrafts",
    categoryName: "Arts & Crafts",
    place: "outdoor",
    activity: "light",
    difficulty: "easy",
    link:"knitting.html",
    description:"Knitting is great"
}];

var myHobbies = [
];




    //Alphabetical Order
        function compareStrings(a, b) {
              a = a.toLowerCase();
              b = b.toLowerCase();

          return (a < b) ? -1 : (a > b) ? 1 : 0;
        }

        data.sort(function(a, b) {
            return compareStrings(a.id, b.id);
        })

        var myHobbies = new Array();
        
        //Show hobbies on explore
        function loadHobbies(){
            myHobbies = JSON.parse(localStorage.getItem("savedHobbies"));
            $("#indvSports").empty();
            $("#subheader").html("<h2>Explore</h2><div id='searchMenu'><form method='get' action='input' id='searchbox' action=''><input id='formInput' type='text' placeholder='search'></form><input type='image' id='submit' onclick='search()' src='img/search.png' alt='Submit'/><img id='menuButton' src='img/menu.png'></div>");
            
            for (i = 0; i < data.length; i++) {
                $("#buttons").append("<a href='#' class='block' id='data[i].id' onclick='loadPage("+i+")'>" + data[i].id + "</a>");
            }
        }
        window.onload = loadHobbies();
        
        //Show and Hide Menu
        var menu = $('#menu'), but = $('#menuButton');
        menu.hide();
$(document).on('click', '*', function(evt) {
    evt.stopPropagation(); //<-- stop the event propagating to ancestral elements
    if ($(this).is(but))   //<-- on button click, toggle visibility of menu
        menu.toggle();
    else if (!$(this).closest(menu).length) //<-- on click outside, hide menu
        menu.hide();
});
        
        //Sift and display categories
        function categorySift(id) {
            menu.hide();
            $('#buttons').empty();
            var categoryId = id;
            
            for (i = 0; i < data.length; i++) {
                if (data[i].category == categoryId) {
                    $("#buttons").append("<a href='#' class='block' id='data[i].id' onclick='loadPage("+i+")'>" + data[i].id + "</a>");
               }
            }
        }
        
        //Sift and display categories for indoor/outdoor
        function categorySiftPlace(id) {
            menu.hide();
            var categoryId = id;
            
            $('#buttons').empty();
            
            for (i = 0; i < data.length; i++) {
                if (data[i].place == categoryId) {
                    $("#buttons").append("<a href='#' class='block' id='data[i].id' onclick='loadPage("+i+")'>" + data[i].id + "</a>");
               }
            }
        }
        
        //Search
        function search(){
            var formInput = document.getElementById("formInput").value.toLowerCase();
            var count = 0;
            
            for (i = 0; i < data.length; i++) {
                if (data[i].id.toLowerCase() == formInput) {
                    count = count + 1;
                    $("#buttons").html("<p id='results'>"+count+" results found for '" + formInput + "'&nbsp;&nbsp;&nbsp;<a href=''> X</a></p><a href='#' class='block' id='data[i].id' onclick='loadPage("+i+")'>" + data[i].id + "</a>");
                    break;
               }
                else{
                    $('#buttons').html("<p id='noResults'>No results found for '" + formInput + "'&nbsp;&nbsp;&nbsp;<a href=''> X</a></p>");
                }
            }        
            document.getElementById("formInput").value='';
        }
        
        //Individual pages
        function loadPage(which) {
            currentI = which;
            $('#buttons').empty();
            $("#myHobbiesSection").empty();
            $("#subheader").html("<style>#subheader{height:60px;}</style><h2><b>"+data[which].id+"</b><br>"+ data[which].categoryName +"</h2><a href='index.html'><img src='img/back.png' id='backButton'/></a><img src='img/add.png' onclick='addHobby("+currentI+")' id='addButton'/>");
            $("#indvSports").html("<p>"+data[which].description+"</p>");
        }
        
        //Individual pages(from My Hobbies page)
        function loadPageMyHobby(which) {
            currentI = which;
            $('#buttons').empty();
            $("#myHobbiesSection").empty();
            $("#subheader").html("<style>#subheader{height:60px;}</style><h2><b>"+myHobbies[which].id+"</b><br>"+ myHobbies[which].categoryName +"</h2><a href='index.html'><img src='img/back.png' id='backButton'/></a><img src='img/add.png' onclick='addHobby("+currentI+")' id='addButton'/>");
            $("#indvSports").html("<p>"+myHobbies[which].description+"</p>");
        }
        
        
        //Add hobby
        function addHobby(which) {
            alert("Would you like to add "+ data[which].id.toLowerCase() +" to your hobbies?");
            myHobbies.push({id: data[which].id, categoryName: data[which].categoryName, description: data[which].description});
            
            localStorage.setItem("savedHobbies", JSON.stringify(myHobbies));
            alert("done");
            
        }
        
        //<a href='#' onclick='editMyHobby' id='editButton'>Edit</a>
        
        
        //My Hobbies Page
        function myHobbiesPage(){
            $("#myHobbiesSection").empty();
            
            myHobbies = JSON.parse(localStorage.getItem("savedHobbies"));
            
            $("#subheader").html("<style>#subheader{height:30px;}</style><h2>My Hobbies</h2>");
            $('#buttons').empty();
            $("#indvSports").empty();
            for (i = 0; i < myHobbies.length; i++) {
                $("#myHobbiesSection").append("<a href='#' class='blockMyHobbies' id='myHobbies[i].id' onclick='loadPageMyHobby("+i+")'>" + myHobbies[i].id + "</a><a href='#' id='deleteButton' onclick='deleteHobby("+i+")'>X</a>");
            }
        }
        
        
        //Lets you edit on My Hobby
//        function deleteHobby(i){
//            alert(myHobbies[i].id);
//            delete myHobbies[i];
//            
//            localStorage.setItem("savedHobbies", JSON.stringify(myHobbies));
//        }
        

答案 1 :(得分:1)

这是sgeddes回答的动态版本。这种技术称为dynamic crosstab.

DECLARE @sql NVARCHAR(MAX)

SELECT @sql = 
'SELECT
    d.name' + CHAR(10)

SELECT @sql = @sql +
'   , MAX(CASE WHEN q.id = ' + CONVERT(VARCHAR(10), id) + ' THEN a.atext END) AS ' 
    + QUOTENAME(qtext) + CHAR(10)
FROM #Questions

SELECT @sql = @sql +
'FROM #Dudes d
LEFT JOIN #Answers a
    INNER JOIN #Questions q
        ON q.id = a.question_id
    ON a.dude_id = d.id
GROUP BY d.id, d.name
ORDER BY d.id'

PRINT(@sql)
EXEC(@sql)

DEMO