1

我不确定这是否可能,而且很难描述。

我想以SELECT这种方式返回查询:

标识符 | 姓名 | 电子邮件 | 狗名 | 鱼名
-------------------------------------------------- -----
44 | 约翰 | john@email.com | 邋遢 |
56 | 简 | 简@email.com | | 河豚
72 | 乔 | 乔@email.com | 火花 | 鳃

有3张表: tbl_option_fields tbl_person tbl_person_optionals

第一个表简单地定义了无限的可选字段。以下是列:

选择 | 选择题
------------------
1 | 狗名
2 | 鱼名
3 | 电子邮件

第二个表只是我为人们保存数据的地方:

标识符 | 姓名
---------------
44 | 约翰
56 | 简
72 | 乔  

最后一张表让我存储存在的任何可选数据pID

身份证 | 标识符 | 选择 | 选择值
----------------------------------
1 | 44 | 1 | 邋遢
2 | 56 | 2 | 河豚
3 | 72 | 1 | 活泼的
4 | 72 | 2 | 鳃
5 | 72 | 3 | joe@email.com
6 | 56 | 3 | jane@email.com
7 | 44 | 3 | john@email.com

SELECT 语句的结果需要opttitle在结果的标题中显示。我不擅长子查询,这可能是一个笨蛋。

这是我的尝试:

SELECT p.*, opt.optval
FROM `tbl_person` p
LEFT OUTER JOIN `tbl_person_optionals` opt ON p.pID = opt.pID 
WHERE 1 

这个查询会导致重复的结果,我相信我明白为什么。

标识符 | 姓名 | 选择值            
-----------------------------------------
44 | 约翰 | john@email.com   
44 | 约翰 | 邋遢   

56 | 简 | jane@email.com
56 | 简 | 河豚

72 | 乔 | joe@email.com  
72 | 乔 | 活泼的  
72 | 乔 | 鳃

希望我解释说我想水平显示可选字段,而不是在行中显示新记录。这可以做到吗?

4

3 回答 3

0

您可以通过将表连接在一起并汇总结果来做到这一点:

select po.pid, p.name,
       MAX(case when o.optId = 'Email' then po.optval end) as Email,
       MAX(case when o.optId = 'Dog Name' then po.optval end) as DogName,
       MAX(case when o.optId = 'Fish Name' then po.optval end) as FishName
from tbl_person_optionals po join
     tbl_person p
     on p.pId = p.pId join
     tbl_optionfields o
     on p.optid = o.optid
group by po.pid, p.name;

这假设您知道列中的内容。 Select语句只能返回一组固定的列,因此如果要为 中的每个值返回一个单独的列,则tbl_optionfields需要动态 SQL(即使用准备语句)。

于 2013-07-10T19:58:32.393 回答
0

你基本上想要的是一个数据透视表。这可以在 MySQL 中完成,就像这篇文章详细描述的那样

但是,为了使用当前表格设计来归档您想要的内容,您必须为table 中的每个选项添加一个SELECT-operator 。只有几个选项这是可以管理的,但是您拥有的选项越多,您的语句就会变得越混乱(并且最终执行速度会变慢)。tbl_option_fields

另一个缺点是每次出现新选项时都必须调整您的陈述。

基本上要么你必须忍受它,要么调整你的桌子设计。可能还有更多选择,但我想归结为这两个。

于 2013-07-10T19:54:24.763 回答
0

这是一个解决方案:

SELECT p.pID, p.Name, 
  MAX(IF(opt.optid=3, opt.optval, NULL)) AS `Email`,
  MAX(IF(opt.optid=1, opt.optval, NULL)) AS `Dog Name`,
  MAX(IF(opt.optid=2, opt.optval, NULL)) AS `Fish Name`
FROM `tbl_person` p
LEFT OUTER JOIN `tbl_person_optionals` opt ON p.pID = opt.pID 
GROUP BY p.pID;

在编写此查询之前,您必须知道所有 optid 及其列标签。这适用于 MySQL,但也适用于支持本机PIVOT命令的 RDBMS 品牌(例如 Microsoft SQL Server)。SQL 要求您在开始检查数据之前定义查询的列;查询无法“添加”更多列,因为它发现了不同的数据值。

因此,您应该查询定义可选字段的第一个表,并使用结果动态编写上面的 SQL 查询。

另一种方法是按照您在示例中显示的那样逐行获取可选字段,然后编写应用程序代码以获取所有行并将它们重新排列为每人一行。

无论哪种方式: 任何动态数据透视查询都需要您在查询之前或查询之后编写更多应用程序代码。

于 2013-07-10T19:54:50.923 回答