Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL:选择父母及其子女_Sql_Sql Server - Fatal编程技术网

SQL:选择父母及其子女

SQL:选择父母及其子女,sql,sql-server,Sql,Sql Server,我相信这是一个常见的问题,但我不确定如何表达它最好 我有两张桌子: Questions { Id, Text... } Answers { Id, QuestionId, Text...} 我想检索问题列表及其答案,以便将结果显示如下: 问题A 对问题A的第一个答复 对问题A的第二个答复 对问题A的第三个答复 问题B 对问题B的第一个答复 ... 等 假设问题表上有一些选择标准 一个非常低效的方法是选择所有相关问题,然后为每个问题选择所有答案。另一种低效的方法是使用左外连接 获取问

我相信这是一个常见的问题,但我不确定如何表达它最好

我有两张桌子:

Questions { Id, Text... }
Answers { Id, QuestionId, Text...}
我想检索问题列表及其答案,以便将结果显示如下:

  • 问题A
    • 对问题A的第一个答复
    • 对问题A的第二个答复
    • 对问题A的第三个答复
  • 问题B
    • 对问题B的第一个答复 ... 等
假设问题表上有一些选择标准

一个非常低效的方法是选择所有相关问题,然后为每个问题选择所有答案。另一种低效的方法是使用左外连接

获取问题和答案的最有效、最简单的方法是什么?它可以在一个查询中完成吗?

对于MySQL(而不是MSSQL),类似的东西可以工作

SELECT q.text, a.text
FROM questions q
LEFT JOIN answers a ON 
    q.quiestionid = q.id
GROUP BY q.id, a.id
ORDER BY q.id
如果您有任何q,请告诉我。

对于MySQL(而不是MSSQL),类似的东西可以工作

SELECT q.text, a.text
FROM questions q
LEFT JOIN answers a ON 
    q.quiestionid = q.id
GROUP BY q.id, a.id
ORDER BY q.id

如果您有任何问题,请告诉我。

为什么您认为左连接效率低下?你会得到一些重复的问题数据,这些问题已经回答了很多次,但这只是额外的几个字节,没什么好担心的

给出的一个答案可以很好地工作(在任何真正的sql引擎中,包括mssql、sqlite等,以及所建议的mysql中),但是是多余的(它在主键上有一个group by,无论如何都不会重复)。因此,以下更简单且排版固定的版本非常好且快速:

SELECT q.id, q.text, a.id, a.text
  FROM questions q
  LEFT JOIN answers a ON a.questionid = q.id
 ORDER BY q.id

您的客户机代码必须注意q.id何时更改,以便按照您的要求“分层”地分组和显示内容——如何进行分组取决于您使用的客户机端语言,例如在Python中,您可以使用
itertools.groupby
非常简单地进行分组和显示(您不需要SQL server端的group by,但您确实需要客户端的group by,无论是使用Python之类的语言提供的工具,还是通过自己实现,都可以按照您的需要显示层次结构).

为什么您认为左连接效率低下?您会得到一些重复的问题数据,这些问题已经回答了很多次,但这只是多余的几个字节,没什么好担心的

给出的一个答案可以很好地工作(在任何真正的sql引擎中,包括mssql、sqlite等,以及它所建议的mysql中),但它是冗余的(它在主键上有一个group by,无论如何都不会重复)。因此,以下更简单且错误固定的版本很好且快速:

SELECT q.id, q.text, a.id, a.text
  FROM questions q
  LEFT JOIN answers a ON a.questionid = q.id
 ORDER BY q.id

您的客户机代码必须注意q.id何时更改,以便按照您的要求“分层”地分组和显示内容——如何进行分组取决于您使用的客户机端语言,例如在Python中,您可以使用
itertools.groupby
非常简单地进行分组和显示(您不需要SQL server端的group by,但您确实需要客户端的group by,无论是使用Python之类的语言提供的工具,还是通过自己实现,都可以按照您的需要显示层次结构).

左外连接根本不会有效率。我不知道你为什么会认为这是一致的-请参阅下面的答案。连接就是为了这个目的。左外连接根本不会有效率。我不知道你为什么会认为这是一致的-请参阅下面的答案。连接就是为了这个目的。你为什么不认为这对MSSQL有效?你只是编写了ANSI SQL。语法在SQL Server.afaik中运行良好,符合ANSI标准的rdbms要求SELECT子句上的列也应出现在GROUP BY子句上。因此,GROUP BY子句中需要包含q.text和a.text。christian的示例不适用于PostgreSQL和MSSQL。上面的示例仅适用于pg和MSSQL,使用以下命令:GROUP BY q.id,a.id,q.text,a.text但是由于.id字段是主键,不会重复,为什么不直接删除无用的组呢?@Michael:你说得对。我在心里跳过了它们,因为它们在这种情况下是绝对无用的(正如Alex指出的)。你为什么不认为这对MSSQL有效?你刚刚编写了ANSI SQL。语法在SQL Server.afaik中可以很好地工作。符合ANSI标准的rdbms要求SELECT子句上的列也应该出现在GROUP BY子句上。因此,GROUP BY子句中需要包含q.text和a.text。christian的示例对PostgreSQL和MSSQL不起作用。上面的只能使用以下方式处理pg和mssql:GROUP BY q.id、a.id、q.text、a.text但由于.id字段是主键,不会重复,为什么不直接删除无用的GROUP BY?!@Michael:你说得对。我在心里跳过了它们,因为在这种情况下它们是绝对无用的(正如Alex指出的).是的,我认为重复数据会导致效率低下-假设在最坏的情况下会有20到100个答案。考虑到简单性,我无论如何都会尝试,并在测试性能后推迟进一步优化。是的,我认为重复数据会导致效率低下-假设我会有20到100个答案n最坏的情况。考虑到简单性,我无论如何都会尝试,并在测试性能后推迟进一步的优化。