如何编写SQL查询,其中一列返回多个结果C#

时间:2016-02-25 21:45:36

标签: c# mysql sql razor

我有两张桌子:

用户:

ID    Name
----------------
1     Bob
2     Dave
3     Mike   

书籍:

ID  UserId   BookName
------------------------
1    1       Cat in Hat
2    1       Happy Birthday
3    1       One Fish
4    2       Goldilocks
5    2       Three Crows
6    3       Hitchhikers

UserId是显示每个用户拥有的图书的关键

在我的html中,我想创建如下所示的输出:

Name       Books Owned
-------------------------
Bob        Cat in Hat, Happy Birthday, One Fish
Dave       Goldilocks, Three Crows
Mike       Hitchhikers

目前我正在使用循环和嵌套查询来执行此操作:

var queryusers = db.Query("SELECT * FROM users");

foreach (var user in queryusers) {
    <span>@user.name</span>
    var querybooks = db.Query("SELECT * FROM books WHERE userid = @0", user.id);
    foreach (book in querybooks ) {
        <span>@book.bookname</span>
    }
}

我知道这不好,但我不知道如何用JOIN做到这一点。如果我尝试:

var queryusersandbooks = db.Query("SELECT * FROM users INNER JOIN books ON users.id = books.userid");

我的查询返回6行,但我只想要3.有没有办法在循环中没有SQL查询的情况下执行此操作?

由于

4 个答案:

答案 0 :(得分:1)

您正在寻找GROUP_CONCAT。尝试这样的事情:

SELECT name AS Name, GROUP_CONCAT(books.bookname SEPARATOR ', ') AS Books 
FROM books INNER JOIN users ON users.id=books.userid 
GROUP BY books.userid;

请记住,GROUP-CONCAT有1024个字符限制,因此如果您需要更多空间,请在执行SQL之前设置更大的阈值,如下所示:

SET SESSION group_concat_max_len = 1000000;
SELECT name AS Name, GROUP_CONCAT(books.bookname SEPARATOR ', ') AS Books 
FROM books INNER JOIN users ON users.id=books.userid 
GROUP BY books.userid;

这是working fiddle

答案 1 :(得分:0)

尝试这样的事情

SELECT u.name,CONCAT_WS(',',b.bookname) AS user_books FROM users u INNER JOIN books b ON u.id = b.userid GROUP BY u.id

答案 2 :(得分:0)

如果我要在mysql中做这样的事情,我会按用户分组并使用group_concat来组合结果:

select users.id, users.name, group_concat(bookname) as books
from users inner join books on books.userid = user.id
group by users.id, users.name

如果您愿意,可以订购并指定分隔符,有关详细信息,请阅读group_concat。如果可能有很多书,或者你希望每本书都是自己的专栏或类似的东西,这会很快崩溃,但在简单的情况下它很好。

答案 3 :(得分:0)

你走在正确的轨道上。在原始代码中,内部foreach也会执行6次,每本书执行一次。

使用下面的代码(基于您自己的代码),查询仍会返回6行,如您所见,但只打印一次用户名。

var queryusersandbooks = db.Query("SELECT * FROM users INNER JOIN books ON users.id = books.userid ORDER BY users.name");

int curruser = 0;
foreach (var userandbook in queryusersandbooks)
{
    if (userandbook.userid != curruser)
    {
        <span>@userandbook.name</span>
        curruser = userandbook.userid;
    }
    <span>@userandbook.bookname</span>
}