2015-03-31 238 views
1

如何在同一个表上进行多个查询,选择不同的列?将同一个表上的多个MySQL查询合并为一个

如果它有帮助......所有查询在SQL语句的选择部分都有一个共同的列。他们都选择了ID,然后是特定的东西。

因此,每个查询需要ID和以下任一项:post_name,post_titlepost_excerpt

此外,如果它有助于简化事情。我正在尝试在这些列中搜索广泛匹配项和精确匹配项。

所以在我的示例中,我将查找:“floor finish”,“floor”或“finish”在以下列中:post_name,post_titlepost_excerpt。全部在同一张表内。

我试图用UNION来实现这个。

这里是我的查询:

Array 
(
    [broad] => Array 
     (
      [floor] => Array 
       (
        [slugs] => SELECT `ID`, `post_name` FROM tps_3_posts WHERE `post_status` = 'publish' AND `post_name` LIKE '%floor%' 
        [titles] => SELECT `ID`, `post_title` FROM tps_3_posts WHERE `post_status` = 'publish' AND `post_title` LIKE '%floor%' 
        [excerpts] => SELECT `ID`, `post_excerpt` FROM tps_3_posts WHERE `post_status` = 'publish' AND `post_excerpt` LIKE '%floor%' 
       ) 

      [finish] => Array 
       (
        [slugs] => SELECT `ID`, `post_name` FROM tps_3_posts WHERE `post_status` = 'publish' AND `post_name` LIKE '%finish%' 
        [titles] => SELECT `ID`, `post_title` FROM tps_3_posts WHERE `post_status` = 'publish' AND `post_title` LIKE '%finish%' 
        [excerpts] => SELECT `ID`, `post_excerpt` FROM tps_3_posts WHERE `post_status` = 'publish' AND `post_excerpt` LIKE '%finish%' 
       ) 

     ) 

    [exact] => Array 
     (
      [slugs] => SELECT `ID`, `post_name` FROM tps_3_posts WHERE `post_status` = 'publish' AND `post_name` LIKE '%floor-finish%' 
      [titles] => SELECT `ID`, `post_title` FROM tps_3_posts WHERE `post_status` = 'publish' AND `post_title` LIKE '%floor finish%' 
      [excerpts] => SELECT `ID`, `post_excerpt` FROM tps_3_posts WHERE `post_status` = 'publish' AND `post_excerpt` LIKE '%floor finish%' 
     ) 

    [combined] => (SELECT `ID`, `post_name` FROM tps_3_posts WHERE `post_status` = 'publish' AND `post_name` LIKE '%floor-finish%') UNION (SELECT `ID`, `post_name` FROM tps_3_posts WHERE `post_status` = 'publish' AND `post_name` LIKE '%floor%') UNION (SELECT `ID`, `post_name` FROM tps_3_posts WHERE `post_status` = 'publish' AND `post_name` LIKE '%finish%') UNION (SELECT `ID`, `post_title` FROM tps_3_posts WHERE `post_status` = 'publish' AND `post_title` LIKE '%floor finish%') UNION (SELECT `ID`, `post_title` FROM tps_3_posts WHERE `post_status` = 'publish' AND `post_title` LIKE '%floor%') UNION (SELECT `ID`, `post_title` FROM tps_3_posts WHERE `post_status` = 'publish' AND `post_title` LIKE '%finish%') UNION (SELECT `ID`, `post_excerpt` FROM tps_3_posts WHERE `post_status` = 'publish' AND `post_excerpt` LIKE '%floor finish%') UNION (SELECT `ID`, `post_excerpt` FROM tps_3_posts WHERE `post_status` = 'publish' AND `post_excerpt` LIKE '%floor%') UNION (SELECT `ID`, `post_excerpt` FROM tps_3_posts WHERE `post_status` = 'publish' AND `post_excerpt` LIKE '%finish%') 
) 

然而,上述结果是有趣的。我似乎得到所有正确的结果,除了每个结果值(应该是列的名称)的关键字始终保持不变。即使分配给它的值可能是post_titlepost_excerpt,它始终为post_name

所以每个结果都有一个IDpost_name。基本上他们的钥匙是错的,但是这些数值似乎是准确的。

我也尝试过这样的事情:

Array 
     (
      [broad] => Array 
       (
        [floor] => SELECT `ID`, `post_name`, `post_title`, `post_excerpt` FROM tps_3_posts WHERE `post_status` = 'publish' AND (`post_name` LIKE '%floor%' OR `post_title` LIKE '%floor%' OR `post_excerpt` LIKE '%floor') 
        [finish] => SELECT `ID`, `post_name`, `post_title`, `post_excerpt` FROM tps_3_posts WHERE `post_status` = 'publish' AND (`post_name` LIKE '%finish%' OR `post_title` LIKE '%finish%' OR `post_excerpt` LIKE '%finish%') 
       ) 

      [exact] => SELECT `ID`, `post_name`, `post_title`, `post_excerpt` FROM tps_3_posts WHERE `post_status` = 'publish' AND (`post_name` LIKE '%floor-finish%' OR `post_title` LIKE '%floor finish%' OR `post_excerpt` LIKE '%floor finish%') 
      [combined] => SELECT `ID`, `post_name`, `post_title`, `post_excerpt` FROM tps_3_posts WHERE `post_status` = 'publish' AND (`post_name` LIKE '%floor-finish%' OR `post_title` LIKE '%floor finish%' OR `post_excerpt` LIKE '%floor finish%') UNION (SELECT `ID`, `post_name`, `post_title`, `post_excerpt` FROM tps_3_posts WHERE `post_status` = 'publish' AND (`post_name` LIKE '%floor%' OR `post_title` LIKE '%floor%' OR `post_excerpt` LIKE '%floor%')) UNION (SELECT `ID`, `post_name`, `post_title`, `post_excerpt` FROM tps_3_posts WHERE `post_status` = 'publish' AND (`post_name` LIKE '%finish%' OR `post_title` LIKE '%finish%' OR `post_excerpt` LIKE '%finish%')) 
     ) 

) 

这是沿着什么,我试图完成的线条更。我希望每个结果都有ID,post_excerpt,post_slugpost_title。如果没有匹配,则显示它们的键值为空,或者完全不显示该键。

第二次尝试的问题是,它只需要三个所需列中的一个匹配。因此,如果它匹配post_excerpt而没有其他地方,它仍然会从post_titlepost_name中提取值。从而导致结果不准确。

我已经阅读了几个似乎是类似的问题,但大多数都没有真正明确的答案......或者...问题/答案更适合于SEPARATE表上的多个查询。

关于在同一个表上组合多个MySQL查询的任何指导或建议?

BY THE WAY ...我在我的例子中使用“组合”作为我的最终查询发送到数据库。

所以再一次......如果列中没有匹配,则显示它们为空或完全忽略结果中的键。

+0

这正是我为什么不经常使用这个网站的原因。每个人都喜欢傲慢和无用,而不是建设性和有益的。 – 2015-03-31 22:03:52

+0

你为什么这么说? – 2015-03-31 22:49:22

+0

我发表的评论是针对做出粗暴评论的人的回应。要么他自己删除它,要么是主持人。 – 2015-04-01 16:25:00

回答

2

由于查询中的UNION语句,您得到错误的“密钥”。您有不同的键名称,但是三个不同列之间的兼容列类型是联合查询。而不是抛出一个错误,数据库引擎刚刚从第一个查询选择列名和使用,对所有的人:

id | post_name # <= column name in first query 
1 | "my post" 

UNION 

id | post_title # <= column name is different, but type is compatible, so UNION succeeds 
1 | "my post title" 

UNION 

id | post_excerpt # <= ditto 
1 | "my post excerpt" 

会导致:

id | post_name # <= column name from first query 
1 | "my post" 
1 | "my post title" 
1 | "my post excerpt" 

这是你是什么经历。

相反,你可以这样做:

id | post_name | post_title | post_excerpt 
1 | "my post" | null  | null  # <= deliberately select nulls for these columns in this query 

UNION 

id | post_name | post_title  | post_excerpt 
1 | null  | "my post title" | null 

UNION 

id | post_name | post_title | post_excerpt 
1 | null  | null  | "my post excerpt" 

这将使你类似的结果:

id | post_name | post_title  | post_excerpt 
1 | "my post" | null   | null 
1 | null  | "my post title" | null 
1 | null  | null   | "my post excerpt" 

随着你的表中,这是一个非常基本的版本可能看起来像:

SELECT ID, post_name, null AS post_title, null AS post_excerpt FROM tps_3_posts 

UNION 

SELECT ID, null AS post_name, post_title, null AS post_excerpt FROM tps_3_posts 

UNION 

SELECT ID, null AS post_name, null AS post_title, post_excerpt FROM tps_3_posts 

这可能更适用于您正在尝试做的事情。 Here's a SQLFiddle如果你想看到它的行动。

+0

我想我明白你的建议。我应该在每个查询中选择所有4列,但强制某些列为空?这可能看起来像一个愚蠢的问题,但你如何故意为某些列选择空值而不是其他值? – 2015-04-01 16:31:36

+0

@MichaelEcklund查看我的基本查询示例的更新答案。 – 2015-04-01 16:38:43

+0

非常感谢Paul。那正是我需要做的。顺便说一句,W3Schools教我做'SELECT column_name AS alias_name',并演示'SELECT alias_name AS column_name'。你的语法是** CORRECT **,而W3Schools的语法是**错误**。当我使用W3School的方式时,MySQL会为无效的语法抛出错误。用你的方式,它完美地工作。 – 2015-04-01 17:10:29

0

正如我在第二种情况下所理解的那样,问题是只有匹配的列应该有值,而其他的应该为空。对于这种情况,您可以在SELECT中使用IF/ELSE或WHEN语句。这个想法是你选择的实际值是该列对应于期望值的值,否则为null。

另一个可能的解决方案是你可以编写例如

SELECT `ID`, `post_name`, `post_title`, 'post_excerpt' 

因此,您选择WHERE语句中条件的字符串值,稍后可以使用该值来了解该行属于哪个属性。