MySQL在右连接条款中的顺序

时间:2015-12-29 20:36:26

标签: mysql sql join sql-order-by

我试图在MySQL中正确加入:

SELECT customers.id,customers.firstname,customers.lastname,customers.email,orders.time,orders.notes,pendings.date_updated,pendings.issue,appointments.closed,appointments.job_description,backup_plans.expiration FROM customers
RIGHT JOIN orders
ON customers.id = orders.customer_id
ORDER BY orders.time DESC LIMIT 1
RIGHT JOIN pendings
ON customers.id = pendings.customer_id
ORDER BY pendings.date_updated DESC LIMIT 1
RIGHT JOIN appointments
ON customers.id = appointments.customer_id
ORDER BY appointments.closed DESC LIMIT 1
RIGHT JOIN backup_plans
ON customers.id = backup_plans.customer_id
ORDER BY backup_plans.expiration DESC LIMIT 1

我的意图是:选择客户'姓名和电子邮件,以及最近的订单,待处理,约会和备份计划探索。当我执行此操作时,我收到语法错误:

#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'RIGHT JOIN pendings
ON customers.id = pendings.customer_id
ORDER BY pendings.d' at line 5

我不熟悉加入,并希望得到任何帮助。

编辑1:

似乎我需要根据DanK的建议制作一个子查询:

SELECT customers.id,customers.firstname,customers.lastname,customers.email,orderstmp.time,orderstmp.notes FROM customers
RIGHT JOIN (
    SELECT orders.time,orders.notes,orders.customer_id FROM orders ORDER BY orders.time DESC LIMIT 1
) as orderstmp ON orderstmp.customer_id = customers.id

但是当我这样做时,我只得到一行结果,而我想要所有客户信息。

编辑2:

根据Tom H的建议,我已经构建了这个查询:

SELECT
    customers.id,
    SQ_O.time,
    SQ_O.notes
FROM customers
LEFT JOIN (
    SELECT
        customers.id,
        orders.time,
        orders.notes
    FROM customers
    LEFT JOIN orders ON orders.customer_id = customers.id
    ORDER BY orders.time DESC LIMIT 1
) AS SQ_O ON SQ_O.id = customers.id

包含所有空白时间和注释字段

SELECT
    customers.id,
    O1.time,
    O1.notes
FROM customers
LEFT JOIN orders AS O1 ON O1.customer_id = O1.id
LEFT JOIN orders AS O2 ON O2.customer_id = customers.id AND O2.time > O1.time WHERE O2.customer_id IS NULL

达到最长执行时间。我猜这是因为我不熟悉MySQL与其他方言相比可能会有什么。

我也尝试了相关子查询

SELECT
    customers.firstname,
    customers.lastname,
    customers.email,
    (
        SELECT CONCAT(orders.time,': ',orders.notes)
        FROM orders
        WHERE orders.customer_id = customers.id
        ORDER BY orders.time DESC LIMIT 1
    ) as last_order
FROM customers

但" last_order"栏目空白。

最终,令人失望的编辑

在尝试了一些非常好的建议,帮助我显着学习SQL之后,我决定编写一个PHP脚本来获取我想要的东西。该项目在一个截止日期之前,所以无论什么工作,都有效。谢谢大家!

4 个答案:

答案 0 :(得分:3)

每个查询只能有一个public enum Card { TWO(2), THREE(3), FOUR(4), FIVE(5), SIX(6), SEVEN(7), EIGHT(8), NINE(9), TEN(10), JACK(10), QUEEN(10), KING(10), ACE(11); private int value; private Card previous; static{ //lets set previous element for cards //we will iterate starting from TWO so its previous should be: Card previous = ACE;//yes ACE for (Card card : values()){ card.previous = previous; previous = card; } } Card(int value){ this.value = value; } public int getValue(){ return value; } public Card getPrevious(){ return previous; //<-- simple getter is enough since we took care // of setting this value earlier in static // initialization block } public String toString(){ return "The value of this card is: " + value; } } 语句。您当然可以使用子查询并将结果集称为虚拟表,但最终只需一个ORDER BY,您只能有一个SELECT

例如:

ORDER BY

将子查询作为虚拟表:

SELECT something
FROM table
ORDER BY something -- One order By

------的修改 --------

有关联接语法的帮助,请尝试以下操作:

SELECT something
FROM (SELECT anotherthing, something
      FROM table
      ORDER BY anotherthing) -- this is an order by in a separate select statement..
ORDER BY something -- still only one Order by

答案 1 :(得分:0)

试试这个:

Queue.get

答案 2 :(得分:0)

您可以通过子查询或其他JOIN来完成此操作。这是每个例子。 (注意:我使用SQL Server,因此我可能会在MySQL中以不同的方式支持我习惯的某些语法)。我只是用Orders做这些例子,但希望你可以把想法扩展到其他表格。

使用子查询:

SELECT
    C.id,
    SQ_O.time,
    SQ_O.notes
FROM
    Customers C
LEFT OUTER JOIN
(
    SELECT
        C2.Customer_ID,
        O.time,
        O.notes
    FROM
        Customers C2
    LEFT OUTER JOIN Orders O ON O.customer_id = C2.id
    ORDER BY
        O.time DESC LIMIT 1
) SQ_O ON SQ_O.customer_id = C.id

使用多个JOIN s:

SELECT
    C.id,
    O1.time,
    O1.notes
FROM
    Customers C
LEFT OUTER JOIN Orders O1 ON O1.customer_id = C.id
LEFT OUTER JOIN Orders O2 ON O2.customer_id = C.id AND O2.time > O1.time
WHERE
    O2.customer_id IS NULL -- Basically we're excluding any rows where another order was found with a later time than O1

如果Orders.time中的完全匹配是可能的,那么您需要选择其他标准。

答案 3 :(得分:0)

只要你可以依赖没有客户让他们最近的两个orders具有相同的time,这应该有效:

SELECT c.firstname, c.lastname, c.email, o.*
FROM customers AS c
LEFT JOIN (
   SELECT customer_id, MAX(`time`) AS maxTime
   FROM orders
   GROUP BY customer_id 
) AS lastO ON c.id = lastO.customer_id
LEFT JOIN orders AS o 
   ON lastO.customer_id = o.customer_id
   AND lastO.maxTime = o.`time`
;

只要其他表也可以依赖每个客户只有一个MAX值,您应该可以为它们附加类似的JOIN。对于客户而言,多个相同的“最后”time\date_updated\closed\etc..的问题是它们会使结果倍增。例如,time中的orders对和同一客户的date_updated中的pending对将导致4行而不是每行“最后”行的两行orders中的该客户与pending中的每个“最后”行配对。