Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/255.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
Php 通过ORDER BY跨3个表的MYSQL UNION_Php_Mysql - Fatal编程技术网

Php 通过ORDER BY跨3个表的MYSQL UNION

Php 通过ORDER BY跨3个表的MYSQL UNION,php,mysql,Php,Mysql,我们有以下声明: (SELECT res_bev.bev_id, property_value.name AS priority FROM res_bev, bev_property, property_value WHERE res_bev.res_id='$resIn' AND bev_property.bev_id=res_bev.bev_id AND bev_property.type_id='23' AND prope

我们有以下声明:

(SELECT res_bev.bev_id, property_value.name AS priority 
    FROM res_bev, bev_property, property_value 
    WHERE res_bev.res_id='$resIn'
        AND bev_property.bev_id=res_bev.bev_id
        AND bev_property.type_id='23'
        AND property_value.id=bev_property.val_id)
UNION
(SELECT res_bev.bev_id, property_value.name as priority 
    FROM res_bev, bev_property, property_value 
    WHERE res_bev.res_id='$resIn' 
        AND bev_property.bev_id=res_bev.bev_id 
        AND bev_property.type_id='22' 
        AND property_value.id=bev_property.val_id)
我们有三张桌子:

Res_bev
res|u id | bev|u id | id

Bev_属性
类型| val | bev | id | id

属性值
姓名| id

我所寻找的是按玻璃价格(type_id='23')然后按瓶子价格(type_id='22')订购的结果,但是由于第一个select返回值为
3456 | 7.5
,第二个返回值为
3456 | 55
,因为价格/玻璃为7.5,价格/瓶子为55如何从第二条SQL语句中消除这些重复项以返回并排序表?


此外,通过左连接创建一个伪表来创建一个包含
bev|u id | price/Glass | price/Bottle
的表也很愚蠢,但是由于这应该能够扩展到多种价格类型,我认为联合会更有效。只要朝着正确的方向推动一下就会有帮助

通过指定bev_property.type_id以匹配包含值的in()子句,可以在1个查询中完成此操作

要仅返回找到的第一个,您应该需要伴随字段
bev_id
的一个字符

要对它们进行排序,只需添加一个适当的降序BY子句。这应该先排序,然后过滤掉第二个
bev\u属性。键入\u id
值。(除非您告诉数据库,否则数据库不会按特定顺序返回任何内容,有些数据库可能有内部约定,或者看起来是这样,但除非您在
SELECT
语句中指定
order BY
子句,否则这决不能保证可重复。)

联合不会更快,因为您必须执行两次整个查找,如果您没有对该字段进行索引,那么您将执行两次匹配1个元素的整个表遍历,而不是执行匹配2个元素的1个表遍历。(在整张桌子上走动通常比较慢,简单的元素之间不匹配)

如果索引正确,我认为执行新的select查询和再次运行查询分析器可能会有一点开销,但我不确定。它可能足够聪明,能够识别出查询之间的相似性,所以这并不重要


不过,在特定数据库上尝试并不总是有害的。每当您尝试使用不同的语句时,这将向您显示查询将执行的操作,以及它是否会遍历整个表、对文件中的数据进行排序等等。

除非我遗漏了什么,或者您的问题中有遗漏

SELECT res_bev.bev_id, 
       property_value.name AS priority 
FROM res_bev, bev_property, property_value 
WHERE res_bev.res_id='$resIn' 
AND bev_property.bev_id=res_bev.bev_id 
AND (bev_property.type_id='23' OR bev_property.type_id='22')
AND property_value.id=bev_property.val_id)
order by bev_property.type_id desc
PS如果你想订一个工会

试着做一些类似的事情

Select * from
(
select ...
Union
select ...
) somenameforqryinparentheses
Order by Somecolumn1, somecolumn2

我认为这个答案可能会有所帮助。好极了,我非常感谢你的解释——在我发布了这篇文章并仔细考虑之后,我认为有一种比UNION更好的方法,尤其是当我们处理成千上万的记录时。然而,有一个问题是,结果的顺序仍然不正确——正如你在那里看到的那样。它们应该是完全描述的,但顺序似乎是否定的……您在一个不可见的字段上排序,以确保在重复的情况下,更高值的字段(23)获胜,您可能也希望在res_bev.bev_id或property_value.name上排序?所以按bev_property.type_id DESC、property_value.name DESC排序?基本上,如果您想影响其输出顺序,请按参数添加额外的顺序。第一种方法的唯一目的是确保正确的副本被过滤掉;明白了,我今晚会玩这个游戏,100%地得到它,让每个人都知道我最终得到了什么;非常感谢@harald的帮助不要忘记,您可以使用子选择来提供要排序的数据:因此,从(我们这里的查询)c按优先级顺序描述中选择res_bev.bev_id,property_value.name作为优先级;这将首先进行筛选,然后获取结果并按照您的意愿对其进行排序,而不会影响筛选。会稍微慢一点,但不会太慢。:)
Select * from
(
select ...
Union
select ...
) somenameforqryinparentheses
Order by Somecolumn1, somecolumn2