This is my code:
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;
How to add where in that code?
where difference <= 3
Every time I write where, I get error message:
Unknown column 'difference' in where clause
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;
Now, Can you use an alias in the WHERE clause in MySQL?
From the MySQL Manual:
It is not allowable to refer to a column alias in a WHERE clause
because the column value might not yet be determined when the WHERE
clause is executed. See Section B.1.5.4, “Problems with Column
Aliases”.
Try below :
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
You can't reference a column alias inside the same SELECT you are declaring it. Either you filter by the column expression (a.stok-a.laku) or you nest it as a subquery and filter it in an outmost scope.
Filter by the column expression:
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!
Nest the subquery:
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!
Use WHERE (a.stok-a.laku) <= 3 not the alias.
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;
You have to first get the a.stok and a.laku , calculate the difference and then store it to a sql variable and use it then in a where clause. Because mysql doesn't calculate the difference first in the select case and then fetches the appropriate rows. You have to do this. I hope this help you
The documentation of the SELECT statement explains:
A select_expr can be given an alias using AS alias_name. The alias is used as the expression's column name and can be used in GROUP BY, ORDER BY, or HAVING clauses.
[...]
It is not permissible to refer to a column alias in a WHERE clause, because the column value might not yet be determined when the WHERE clause is executed.
See Section B.5.4.4, "Problems with Column Aliases".
The solution is simple: don't use the alias in the WHERE clause, use the aliased expression instead:
SELECT ... (a.stok-a.laku) as difference, ...
...
WHERE a.stok-a.laku <= 3
...
MySQL -- as with all other databases -- does not allow table aliases in the WHERE clause. However, MySQL extends the HAVING clause to allow such filtering. So, you can do:
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;
Notes:
I prefer COALESCE() to IFNULL() because the former is the ANSI-standard function.
I simplified the last subquery. The JOIN seems unnecessary. (It might be under some circumstances, but I'm guessing it is not.)
You probably don't need the COALESCE()/IFNULL() for the SUM()s. I left them in, but the NULLs are ignored in aggregation functions.
I have following two queries
1)
SELECT `domains`.`name` , `pageviews`.`domain_id` , COUNT( `pageviews`.`domain_id` )
FROM `pageviews`
LEFT JOIN `domains` ON ( `domains`.`id` = `pageviews`.`domain_id`
AND `domains`.`user_id` = '129' )
WHERE `pageviews`.`user_id` = '129'
GROUP BY `pageviews`.`domain_id`
ORDER BY COUNT( `pageviews`.`domain_id` ) DESC
2)
SELECT `domains`.`name` , `visitors`.`ip` , `visitors`.`domain_id` , COUNT( `visitors`.`domain_id` )
FROM `visitors`
LEFT JOIN `domains` ON ( `domains`.`id` = `visitors`.`domain_id`
AND `domains`.`user_id` = '129' )
WHERE `visitors`.`user_id` = '129'
GROUP BY `visitors`.`domain_id`
ORDER BY COUNT( `visitors`.`domain_id` ) DESC
I want to combine these queries.
this is required for cakephp pagination because i want to show data in table and want to sort acc. to visitors and pageviews if i want.
associations are 1) domains has many visitors 2) domains has many pageviews
Try this:
SELECT
pv.name,pv.domain_id,pv.counter as page_visits, v.ip, v.counter as visits
FROM (
SELECT `domains`.`name` , `pageviews`.`domain_id` , COUNT( `pageviews`.`domain_id` ) as counter
FROM `pageviews`
LEFT JOIN `domains` ON ( `domains`.`id` = `pageviews`.`domain_id`
AND `domains`.`user_id` = '129' )
WHERE `pageviews`.`user_id` = '129'
GROUP BY `pageviews`.`domain_id`
ORDER BY COUNT( `pageviews`.`domain_id` ) DESC
) as pv
LEFT JOIN (
SELECT `domains`.`name` , `visitors`.`ip` , `visitors`.`domain_id` , COUNT( `visitors`.`domain_id` ) as counter
FROM `visitors`
LEFT JOIN `domains` ON ( `domains`.`id` = `visitors`.`domain_id`
AND `domains`.`user_id` = '129' )
WHERE `visitors`.`user_id` = '129'
GROUP BY `visitors`.`domain_id`
ORDER BY COUNT( `visitors`.`domain_id` ) DESC
) as v
ON pv.domain_id = v.domain_id
SELECT DISTINCT (
A.`id`
), A.`id` , A.`no` , B.amount, SUM( A.`outward` * A.`price` ) AS total, A.`outward_date`
FROM `outward` A
INNER JOIN franchisees B
INNER JOIN store C
INNER JOIN shoppe D
WHERE B.user_id = C.user_id
AND (C.pos_id = A.no)//(C.pos_id = A.no OR (D.id = A.no)
OR (D.id = A.no)
AND A.outward_date = '2012-02-10'
GROUP BY A.req_id
ORDER BY A.no ASC , A.`d` ASC , B.amount ASC
The problem in this query is that the SUM( A.outward * A.price ) AS total comes differently which is not related to
ouptut
id sum(outward * price)
12021030738-105 485.220000000000
1202104186-104 2504.410000000000
output displayed
12021030738-105 32557.33
1202104186-104 6307.86
i guess the problem is with the OR statement? can anyone find the issue with the query
Try below. enclose OR Conditions in a parenthesis:
SELECT DISTINCT (
A.`id`
), A.`id` , A.`no` , B.amount, SUM( A.`outward` * A.`price` ) AS total, A.`outward_date`
FROM `outward` A
INNER JOIN franchisees B
INNER JOIN store C
INNER JOIN shoppe D
WHERE B.user_id = C.user_id
AND ((C.pos_id = A.no) OR (D.id = A.no))
AND A.outward_date = '2012-02-10'
GROUP BY A.req_id
ORDER BY A.no ASC , A.`d` ASC , B.amount ASC
Anyone can help me, I am a bit stuck.
I have this query which works like a charm
SELECT * ,
matches - falsepositives AS hits
FROM (
SELECT c. * ,
IFNULL( p.total, 0 ) AS matches,
(
SELECT COUNT( * )
FROM ci_falsepositives n
WHERE n.addressbook_id = c.reference
AND n.sanction_key
IN (
SELECT sanction_key
FROM ci_matched_sanctions
)
) AS falsepositives
FROM ci_address_book c
LEFT JOIN (
SELECT addressbook_id,
COUNT( match_id ) AS total
FROM ci_matched_sanctions
GROUP BY addressbook_id
) AS p
ON c.id = p.addressbook_id
) AS S
WHERE matches > 0
ORDER BY hits DESC
But I would like to change it to sort where HITS are more than 0, but it tells me it doesn't know hits... Is it because it's a calculation of 2 items?
You can't use an aliases column in a WHERE clause. You need to rewrite it:
SELECT * ,
matches - falsepositives AS hits
FROM (
SELECT c. * ,
IFNULL( p.total, 0 ) AS matches,
(
SELECT COUNT( * )
FROM ci_falsepositives n
WHERE n.addressbook_id = c.reference
AND n.sanction_key
IN (
SELECT sanction_key
FROM ci_matched_sanctions
)
) AS falsepositives
FROM ci_address_book c
LEFT JOIN (
SELECT addressbook_id,
COUNT( match_id ) AS total
FROM ci_matched_sanctions
GROUP BY addressbook_id
) AS p
ON c.id = p.addressbook_id
) AS S
WHERE matches - falsepositives > 0
ORDER BY hits DESC
Or use a subquery:
SELECT * FROM (
SELECT * ,
matches - falsepositives AS hits
FROM (
SELECT c. * ,
IFNULL( p.total, 0 ) AS matches,
(
SELECT COUNT( * )
FROM ci_falsepositives n
WHERE n.addressbook_id = c.reference
AND n.sanction_key
IN (
SELECT sanction_key
FROM ci_matched_sanctions
)
) AS falsepositives
FROM ci_address_book c
LEFT JOIN (
SELECT addressbook_id,
COUNT( match_id ) AS total
FROM ci_matched_sanctions
GROUP BY addressbook_id
) AS p
ON c.id = p.addressbook_id
) AS S
) AS S2
WHERE hits > 0
ORDER BY hits DESC