Это мой код:
select a.id_brg, a.nm_brg, a.jen_sat, a.nm_kat,a.stok,a.laku, (a.stok-a.laku) as difference from (SELECT barang.id_brg, barang.nm_brg, jen_sat, nm_kat, SUM( IFNULL( stok_brg.stok, 0 ) ) AS stok, IFNULL( laku, 0 ) AS laku
FROM barang
JOIN satuan ON barang.id_sat = satuan.id_sat
JOIN kategori ON barang.id_kat = kategori.id_kat
LEFT JOIN stok_brg ON barang.id_brg = stok_brg.id_brg
LEFT JOIN (
SELECT barang.id_brg, SUM( IFNULL( brg_laku.dibeli, 0 ) ) AS laku
FROM barang, brg_laku
WHERE barang.id_brg = brg_laku.id_brg
GROUP BY barang.id_brg ASC
) AS brg_laku ON barang.id_brg = brg_laku.id_brg
GROUP BY barang.id_brg ASC) as a;
Как добавить, where
в этом коде?
where difference <= 3
Каждый раз, когда я пишу where
, я получаю сообщение об ошибке:
Неизвестная разность столбцов в разделе where
SELECT a.id_brg,
a.nm_brg,
a.jen_sat,
a.nm_kat,
a.stok,
a.laku,
(a.stok-a.laku) as difference
FROM (
SELECT barang.id_brg,
barang.nm_brg,
jen_sat,
nm_kat,
SUM(IFNULL(stok_brg.stok, 0)) AS stok,
IFNULL(laku, 0) AS laku
FROM barang
JOIN satuan ON barang.id_sat = satuan.id_sat
JOIN kategori ON barang.id_kat = kategori.id_kat
LEFT JOIN stok_brg ON barang.id_brg = stok_brg.id_brg
LEFT JOIN (
SELECT barang.id_brg,
SUM(IFNULL( brg_laku.dibeli, 0 )) AS laku
FROM barang
INNER JOIN brg_laku
ON barang.id_brg = brg_laku.id_brg
GROUP BY barang.id_brg ASC
) AS brg_laku
ON barang.id_brg = brg_laku.id_brg
GROUP BY barang.id_brg ASC
) as a
WHERE (a.stok-a.laku) <= 3;
Теперь, можете ли вы использовать псевдоним в предложении WHERE в MySQL?
Из руководства MySQL:
Недопустимо ссылаться на псевдоним столбца в предложении WHERE, поскольку значение столбца может еще не определяться при выполнении предложения WHERE. См. Раздел B.1.5.4 " Проблемы с псевдонимами столбцов ".
MySQL - как и во всех других базах данных - не разрешает псевдонимы таблиц в WHERE
. Однако MySQL расширяет предложение HAVING
, чтобы разрешить такую фильтрацию. Итак, вы можете сделать:
SELECT a.id_brg, a.nm_brg, a.jen_sat, a.nm_kat, a.stok, a.laku,
(a.stok - a.laku) as difference
FROM (SELECT barang.id_brg, barang.nm_brg, jen_sat, nm_kat,
SUM(COALESCE(stok_brg.stok, 0 )) AS stok,
COALESCE( laku, 0 ) AS laku
FROM barang JOIN
satuan
ON barang.id_sat = satuan.id_sat JOIN
kategori
ON barang.id_kat = kategori.id_kat LEFT JOIN
stok_brg
ON barang.id_brg = stok_brg.id_brg LEFT JOIN
(SELECT brg_laku.id_brg, SUM(COALESCE(brg_laku.dibeli, 0)) AS laku
FROM brg_laku
GROUP BY brg_laku.id_brg
) brg_lak
ON barang.id_brg = brg_laku.id_brg
GROUP BY barang.id_brg
) as a
HAVING difference <= 3;
Заметки:
COALESCE()
для IFNULL()
потому что первая является стандартной функцией ANSI.JOIN
кажется ненужным. (Возможно, при некоторых обстоятельствах, но я предполагаю, что это не так.)COALESCE()
/IFNULL()
для SUM()
. Я оставил их, но NULL
игнорируются в функциях агрегации.Попробуйте ниже:
Select * from (select a.id_brg, a.nm_brg, a.jen_sat, a.nm_kat,a.stok,a.laku, (a.stok-a.laku) as difference from (SELECT barang.id_brg, barang.nm_brg, jen_sat, nm_kat, SUM( IFNULL( stok_brg.stok, 0 ) ) AS stok, IFNULL( laku, 0 ) AS laku
FROM barang
JOIN satuan ON barang.id_sat = satuan.id_sat
JOIN kategori ON barang.id_kat = kategori.id_kat
LEFT JOIN stok_brg ON barang.id_brg = stok_brg.id_brg
LEFT JOIN (
SELECT barang.id_brg, SUM( IFNULL( brg_laku.dibeli, 0 ) ) AS laku
FROM barang, brg_laku
WHERE barang.id_brg = brg_laku.id_brg
GROUP BY barang.id_brg ASC
) AS brg_laku ON barang.id_brg = brg_laku.id_brg
GROUP BY barang.id_brg ASC) as a;select a.id_brg, a.nm_brg, a.jen_sat, a.nm_kat,a.stok,a.laku, (a.stok-a.laku) as difference from (SELECT barang.id_brg, barang.nm_brg, jen_sat, nm_kat, SUM( IFNULL( stok_brg.stok, 0 ) ) AS stok, IFNULL( laku, 0 ) AS laku
FROM barang
JOIN satuan ON barang.id_sat = satuan.id_sat
JOIN kategori ON barang.id_kat = kategori.id_kat
LEFT JOIN stok_brg ON barang.id_brg = stok_brg.id_brg
LEFT JOIN (
SELECT barang.id_brg, SUM( IFNULL( brg_laku.dibeli, 0 ) ) AS laku
FROM barang, brg_laku
WHERE barang.id_brg = brg_laku.id_brg
GROUP BY barang.id_brg ASC
) AS brg_laku ON barang.id_brg = brg_laku.id_brg
GROUP BY barang.id_brg ASC) as a)fq where difference <= 3
Вы не можете ссылаться на псевдоним столбца внутри того же самого SELECT
вы его объявляете. Либо вы фильтруете по выражению столбца (a.stok-a.laku
), либо вы a.stok-a.laku
его в качестве подзапроса и фильтруете его в крайнем объеме.
Фильтровать по выражению столбца:
select
a.id_brg,
a.nm_brg,
a.jen_sat,
a.nm_kat,
a.stok,
a.laku,
(a.stok-a.laku) as difference
from
(SELECT
barang.id_brg,
barang.nm_brg,
jen_sat,
nm_kat,
SUM( IFNULL( stok_brg.stok, 0 ) ) AS stok, IFNULL( laku, 0 ) AS laku
FROM barang
JOIN satuan ON barang.id_sat = satuan.id_sat
JOIN kategori ON barang.id_kat = kategori.id_kat
LEFT JOIN stok_brg ON barang.id_brg = stok_brg.id_brg
LEFT JOIN (
SELECT
barang.id_brg,
SUM( IFNULL( brg_laku.dibeli, 0 ) ) AS laku
FROM
barang, brg_laku
WHERE
barang.id_brg = brg_laku.id_brg
GROUP BY
barang.id_brg ASC
) AS brg_laku
ON barang.id_brg = brg_laku.id_brg
GROUP BY
barang.id_brg ASC) as a
WHERE
a.stok-a.laku <= 3 -- Here!
Вложить подзапрос:
SELECT
X.*
FROM
(
select
a.id_brg,
a.nm_brg,
a.jen_sat,
a.nm_kat,
a.stok,
a.laku,
(a.stok-a.laku) as difference
from
(SELECT
barang.id_brg,
barang.nm_brg,
jen_sat,
nm_kat,
SUM( IFNULL( stok_brg.stok, 0 ) ) AS stok, IFNULL( laku, 0 ) AS laku
FROM barang
JOIN satuan ON barang.id_sat = satuan.id_sat
JOIN kategori ON barang.id_kat = kategori.id_kat
LEFT JOIN stok_brg ON barang.id_brg = stok_brg.id_brg
LEFT JOIN (
SELECT
barang.id_brg,
SUM( IFNULL( brg_laku.dibeli, 0 ) ) AS laku
FROM
barang, brg_laku
WHERE
barang.id_brg = brg_laku.id_brg
GROUP BY
barang.id_brg ASC
) AS brg_laku
ON barang.id_brg = brg_laku.id_brg
GROUP BY
barang.id_brg ASC) as a
) AS X
WHERE
X.difference <= 3 -- Here!
Используйте WHERE (a.stok-a.laku) <= 3
не псевдоним.
SELECT a.id_brg, a.nm_brg, a.jen_sat, a.nm_kat,a.stok,a.laku, (a.stok-a.laku) difference FROM(SELECT B.id_brg, B.nm_brg, jen_sat, nm_kat, SUM( IFNULL(SB.stok, 0 )) stok, IFNULL(laku, 0) laku
FROM barang B
JOIN satuan S ON B.id_sat = S.id_sat
JOIN kategori ON barang.id_kat = kategori.id_kat
LEFT JOIN stok_brg SB ON B.id_brg = SB.id_brg
LEFT JOIN (SELECT B.id_brg, SUM( IFNULL(BL.dibeli, 0)) laku
FROM barang B
INNER JOIN brg_laku BL ON B.id_brg = BL.id_brg
WHERE (a.stok-a.laku) <= 3
GROUP BY B.id_brg ASC) brg_laku BL ON B.id_brg = BL.id_brg
GROUP BY B.id_brg ASC) a;
Вы должны сначала получить a.stok и a.laku, вычислить разницу, а затем сохранить ее в переменной sql и использовать ее затем в предложении where. Поскольку mysql не вычисляет разницу сначала в случае выбора, а затем извлекает соответствующие строки. Вы должны это сделать. Надеюсь, это поможет вам
Документация SELECT
объясняет:
При
select_expr
может быть присвоен псевдоним с использованиемAS alias_name
. Псевдоним используется как имя столбца выражения и может использоваться в предложенияхGROUP BY
,ORDER BY
илиHAVING
.[...]
Недопустимо ссылаться на псевдоним столбца в предложении
WHERE
, поскольку значение столбца может еще не определяться при выполненииWHERE
.
См. Раздел B.5.4.4 "Проблемы с псевдонимами столбцов".
Решение прост: не используйте псевдоним в WHERE
, вместо этого используйте выражение с псевдонимом:
SELECT ... (a.stok-a.laku) as difference, ...
...
WHERE a.stok-a.laku <= 3
...
where (a.stok-a.laku) <= 3
where
. Ищите название вашего продукта СУБД иalias
здесь на SO.