mysql为什么变量在if中没有变化

时间:2014-09-02 03:46:05

标签: mysql sql

我有一个mysql查询和IF子句。如果为false,则@cid更改为category_id,@ a必须更改为1.突出显示的行下方的行必须再次为@a。

@a is not changing

为什么在@cid改变时@a保持不变?

SET @a:=0;
SET @cid:=0;
SELECT @a, @cid, q.* FROM (
    SELECT *
    FROM photos
    ORDER BY category_id
) AS q
WHERE IF(@cid=q.category_id, @a:=@a+1, (@a:=1) AND (@cid:=q.category_id))

期望目标

每个新的category_id - @a必须一次又一次地从1开始

所有这一切

我有一个带照片的画廊。几乎每张照片都有一个类别

所以我有一个图库类别页面,您可以在其中查看所有类别和每张照片的4张照片

所以基本上我需要从每个类别中限制4

可能的解决方案

我可以简单地选择所有类别ID,然后预测

select * from photos where category_id = 1 LIMIT 4
select * from photos where category_id = 2 LIMIT 4
...

和联盟,但我有点不喜欢20多个选择

所以当我计算照片并尝试使用嵌套选择时只有4个

完整查询

SET @a:=0;
SET @cid:=0;
SELECT @a, @cid, q.* FROM (
    SELECT
    c.id AS cid,
    c.title AS category_title,
    c.slug AS category_slug,
    i.id AS image_id,
    i.title AS image_title,
    i.slug AS image_slug,
    i.place AS image_place,
    i.created_at AS image_date
    FROM categories AS c
    JOIN photos AS i 
    ON c.id = i.category_id
    WHERE c.visible AND i.visible
    GROUP BY i.id
    HAVING COUNT(i.id) > 0
    ORDER BY c.priority, c.title, i.priority, i.title
) AS q
WHERE IF(@cid=q.cid, @a:=@a+1, (@a:=1) AND (@cid:=q.cid))
AND @a <= 4

但是 - 它不会将@a设置为1,就像上面的简化版本一样


愚蠢但是工作解决方案(第3条腿)

当我添加选择1 AS时 并改变@a:= q.one - IT WORKS 但很奇怪

愚蠢的工作代码

SET @a:=0;
SET @cid:=0;
SELECT @a, @cid, q.* FROM (
    SELECT *, 1 AS ONE
    FROM photos
    ORDER BY category_id
) AS q
WHERE IF(@cid=q.category_id, @a:=@a+1, (@a:=q.one) AND (@cid:=q.category_id))

所以主要问题 - 为什么不是@a:= 1个工作和@a:= q.one是否有效?

1 个答案:

答案 0 :(得分:0)

你在找这个吗?

SELECT rn, id, category_id, title
  FROM
(
  SELECT *, @a := IF(@c = category_id, @a + 1, 1) rn, @c := category_id
    FROM photos CROSS JOIN (SELECT @c := NULL, @a := 0) i
   ORDER BY category_id
) q
 WHERE rn <= 4;

输出:

| RN | ID | CATEGORY_ID |  TITLE |
|----|----|-------------|--------|
|  1 | 43 |           1 | Title1 |
|  1 | 28 |           2 | Title2 |
|  2 | 42 |           2 | Title3 |
|  1 | 11 |           3 | Title4 |
|  1 |  3 |           4 | Title5 |
|  2 | 29 |           4 | Title6 |
|  3 | 33 |           4 | Title7 |

这是 SQLFiddle 演示


以下是修复代码以生成正确的行号

SET @a:=0;
SET @cid:=0;   
SELECT @a, @cid, q.*, @cid:=q.category_id FROM (
    SELECT *
    FROM photos
    ORDER BY category_id
) AS q
WHERE @a := IF(@cid=q.category_id, @a+1, 1)

这是 SQLFiddle 演示

SQL语句执行的顺序很重要。