Sql server errors in query - mysql

I am trying to collaborate 3 queries to perform arithmetic operation. The queries are shown in
(SELECT ITEM_ID,ISNULL(SUM(REC_GOOD_QTY),0)
FROM INVENTORY_ITEM
WHERE COMPANY_ID = 1
AND INVENTORY_ITEM.COMPANY_BRANCH_ID = 1
AND INVENTORY_ITEM.INV_ITEM_STATUS = 'Inward'
AND GRN_DATE < CAST('2017-01-10 00:00:00.0' AS DATETIME)
GROUP BY INVENTORY_ITEM.ITEM_ID) -
(SELECT ITEM_ID, SUM ( TOTAL_LITRE )
FROM STOCK_REQUISITION_ITEM B, STOCK_REQUISITION A
WHERE A.ID = B.REQUISITION_ID
AND A.COMPANY_ID = 1
AND A.REQ_FROM_BRANCH_ID = 1
AND A.REQUISITION_DATE < CAST('2017-01-10 00:00:00.0' AS DATETIME)
GROUP BY B.ITEM_ID) +
(SELECT ITEM_ID, SUM ( RETURN_QUANTITY )
FROM STOCK_RETURN_ITEM B, STOCK_RETURN A
WHERE A.ID = B.STOCK_RETURN_ID
AND A.COMPANY_ID = 1
AND A.COMPANY_BRANCH_ID = 1
AND A.RETURN_DATE <= CAST('2017-01-10 00:00:00.0' AS DATETIME)
GROUP BY B.ITEM_ID)
I am getting this error.
[Err] 42000 - [SQL Server]Incorrect syntax near '-'.
42000 - [SQL Server]Incorrect syntax near '+'

Not much to go on here for details. And we aren't actually sure if you are using mysql or sql server but pretty sure you are using sql server. I think you can accomplish what you are trying to do with something along these lines.
with Iventory as
(
SELECT i.ITEM_ID
, GoodQty = ISNULL(SUM(i.REC_GOOD_QTY), 0)
FROM INVENTORY_ITEM i
WHERE COMPANY_ID = 1
AND i.COMPANY_BRANCH_ID = 1
AND i.INV_ITEM_STATUS = 'Inward'
AND i.GRN_DATE < '2017-01-10'
GROUP BY i.ITEM_ID
)
, StockRequisition as
(
SELECT ITEM_ID
, TotalLitre = SUM(TOTAL_LITRE)
FROM STOCK_REQUISITION_ITEM B
JOIN STOCK_REQUISITION A ON A.ID = B.REQUISITION_ID
WHERE A.COMPANY_ID = 1
AND A.REQ_FROM_BRANCH_ID = 1
AND A.REQUISITION_DATE < '2017-01-10'
GROUP BY B.ITEM_ID
)
StockReturn as
(
SELECT ITEM_ID
, ReturnQuantity = SUM(RETURN_QUANTITY)
FROM STOCK_RETURN_ITEM B
JOIN STOCK_RETURN A ON A.ID = B.STOCK_RETURN_ID
WHERE A.COMPANY_ID = 1
AND A.COMPANY_BRANCH_ID = 1
AND A.RETURN_DATE <= '2017-01-10'
GROUP BY B.ITEM_ID
)
select i.ITEM_ID
, MyCalculation = i.GoodQty - isnull(Req.TotalLitre, 0) + isnull(sr.ReturnQuantity, 0)
from Inventory i
left join StockRequisition sr on sr.ITEM_ID = i.ITEM_ID
left join StockReturn Req on Req.ITEM_ID = i.ITEM_ID

In your queries you always returns two fields ITEM_ID and a numeric field.
To apply an arithmetical operation you must return one numeric field
The first query:
SELECT ITEM_ID,ISNULL(SUM(REC_GOOD_QTY),0)
becomes
SELECT ISNULL(SUM(REC_GOOD_QTY),0)
The second query:
SELECT ITEM_ID, SUM ( TOTAL_LITRE )
becomes
SELECT SUM ( TOTAL_LITRE )
The third query:
SELECT ITEM_ID, SUM ( RETURN_QUANTITY )
becomes
SELECT SUM ( RETURN_QUANTITY )
So the GROUP BY returns more than one row per query
UPDATE
i try to rewrite your query:
SELECT DISTINCT ii.item_id,
ISNULL(
(SELECT SUM(ii2.rec_good_qty)
FROM inventory_item ii2
WHERE ii2.item_id = ii.item_id
AND ii.company_id = 1
AND ii.company_branch_id = 1
AND ii.inv_item_status = 'Inward'
AND ii.grn_date < CAST('2017-01-10 00:00:00.0' AS DATETIME))
,0) -
ISNULL(
(SELECT SUM(total_litre)
FROM stock_requisition_item b
JOIN stock_requisition a
ON a.id = b.requisition_id
WHERE a.company_id = 1
AND a.req_from_branch_id = 1
AND a.requisition_date < CAST('2017-01-10 00:00:00.0' AS DATETIME))
,0) +
ISNULL(
(SELECT SUM(return_quantity)
FROM stock_return_item b
JOIN stock_return a
ON a.id = b.stock_return_id
WHERE a.company_id = 1
AND a.company_branch_id = 1
AND a.return_date <= CAST('2017-01-10 00:00:00.0' AS DATETIME))
,0) AS result
FROM inventory_item ii
WHERE ii.company_id = 1
AND ii.company_branch_id = 1
AND ii.inv_item_status = 'Inward'
AND ii.grn_date < CAST('2017-01-10 00:00:00.0' AS DATETIME)

Related

SQL join table lower date and lower id

I have got the following two tables
START AND REPEAT
START
INSPECID=======SCORE
1--------------3
2--------------1
3--------------4
REPEAT
ID========INSPECID========SCORE========DATE
1---------1---------------9------------12/01/2016
2---------1---------------1------------11/01/2016
3---------2---------------2------------29/01/2016
4---------2---------------4------------01/01/2016
5---------2---------------3------------22/01/2016
6---------2---------------5------------02/01/2016
7---------2---------------1------------11/01/2016
8---------2---------------1------------01/01/2016
9---------3---------------1------------02/01/2016
10--------3---------------2------------09/01/2016
I am expecting as below
INCREASED------1
DECREASED------2
EQUAL----------0
Rules
1) Join tables by INSPECID
2) When more than 1 INSPECID is found in REPEAT table consider the score from the lower date.
3) when both INSPECID is matched and date is matched than consider the lower ID in the REPEAT table, so ID 4 and ID 8 has same date and same INPECTID but consider the ID 4 score which is 4.
Do a self join with REPEAT table to pick the oldest row
select s.*,a.*
from `START` s
join `REPEAT` a on s.INSPECID = a.INSPECID
left join `REPEAT` b on a.INSPECID = b.INSPECID
and case when a.DATE = b.DATE
then a.ID > b.ID
else a.DATE > b.DATE
end
where b.INSPECID is null
For conflict when INSPECID and DATE is same use CASE to choose row with lowest ID
Demo
Updated for desired result set
select t.result,count(t1.result) cnt
from (
select 'Increased' result
union
select 'Decreased' result
union
select 'Equal' result
) t
left join (
select s.score,a.id,a.DATE,
case when s.SCORE > a.SCORE
then 'Increased'
when s.SCORE < a.SCORE
then 'Decreased'
else 'Equal'
end result
from `START` s
join `REPEAT` a on s.INSPECID = a.INSPECID
left join `REPEAT` b on a.INSPECID = b.INSPECID
and case when a.DATE = b.DATE
then a.ID > b.ID
else a.DATE > b.DATE
end
where b.INSPECID is null
) t1 using(result)
group by t.result
Demo
This is a bit tricky. The following uses the group_concat() trick for calculating the first and last scores. It then puts these into the categories that you want:
select w.which, count(r.INSPECID)
from (select 'DECREASING' as which union all
select 'INCREASING' as which union all
select 'EQUAL' as which
) w left join
(select r.INSPECID,
(substring_index(group_concat(score order by date), ',', 1) + 0) as first_score,
(substring_index(group_concat(score order by date desc), ',', 1) + 1) as last_score
from repeat r
group by INSPECID
) r
ON (last_score > first_score and w.which = 'INCREASING') or
(last_score < first_score and w.which = 'DECREASING') or
(last_score = first_score and w.which = 'INCREASING')
group by w.which;
Note that the first table is not necessary.

Combining the result of two queries to one result SQL

I'm trying t create a compare, now i'm only able to make it as multiple result (two different result).
both of the result above is from two queries.
My first result query
SELECT
customercode,
CONVERT(DATE, TransDate) transdate,
SUM(TotalReceivable) AS total
FROM
SalesOrderHeader
WHERE
CustomerCode = 'K-MDMM4'
AND TransDate BETWEEN '2016-07-25' AND '2016-07-30'
GROUP BY
CONVERT(DATE, TransDate), customercode
and my second query
SELECT
b.OutletCode AS outlet,
tanggal,
(cash + cc + dc + flash + piutang + reject + disc50 +
isnull(spesial_item,0)) total
FROM
transaksi a
LEFT JOIN
Outlet b ON a.Outlet = b.OutletCode
LEFT JOIN
area c ON b.areacode = c.areacode
WHERE
b.active = 1
AND b.OutletCode LIKE 'K-MDMM4'
AND flag = 1
AND tanggal BETWEEN '2016-07-25' AND '2016-07-30'
GROUP BY
b.OutletCode, tanggal, cash, cc, dc, flash,
piutang, reject, disc50, spesial_item, ba, mpm, tf,
ul,remarks
ORDER BY
tanggal DESC
I want this result.
customercode | transdate | total_tbl1 | total_tbl2
K-MDMM4 2016-07-25 6004050 6004050
K-MDMM4 2016-07-26 6880340 6880340
K-MDMM4 2016-07-27 5745040 5745040
K-MDMM4 2016-07-28 7424820 7424820
I can't use jsfiddle :(. I don't know why. I can't create table via queries.
From now, I have this query
SELECT
b.OutletCode AS outlet,
tanggal,
(cash + cc + dc + flash + piutang + reject + disc50 +
isnull(spesial_item, 0)) total,
SUM(d.TotalReceivable) AS total
FROM
transaksi a
LEFT JOIN
Outlet b ON a.Outlet = b.OutletCode
LEFT JOIN
area c ON b.areacode = c.areacode
LEFT JOIN
salesorderheader d ON CONVERT(DATE, a.tanggal) = CONVERT(DATE, d.transdate)
WHERE
b.active = 1
AND b.BrandCode LIKE '%%'
AND b.OutletCode LIKE '%%'
AND flag = 1
AND YEAR(tanggal) = '2016'
AND MONTH(tanggal) = '7'
AND outlet = 'K-MDMM4'
GROUP BY
OutletCode, tanggal, cash, cc, dc, flash,
piutang, reject, disc50, spesial_item, transdate, totalreceivable
ORDER BY
tanggal DESC
and the result so far from my desired result....
Combine both queries into a single join and select
SELECT tbl1.customercode,
CAST(tbl1.transdate AS DATE) AS transdate,
tbl1.total AS total_tbl1,
tbl2.total AS total_tbl2
FROM
(
-- Query 1
SELECT customercode,convert(date,TransDate) transdate,SUM(TotalReceivable) as total
FROM SalesOrderHeader
where CustomerCode = 'K-MDMM4'
and TransDate between '2016-07-25' and '2016-07-30'
group by convert(date,TransDate),customercode
) AS tbl1
INNER JOIN (
-- Query 2
select b.OutletCode as outlet,tanggal, (cash + cc + dc + flash + piutang + reject + disc50 +
isnull(spesial_item,0)) total From transaksi a
left join Outlet b on a.Outlet = b.OutletCode
left join area c on b.areacode = c.areacode
where b.active = 1 and b.OutletCode like 'K-MDMM4' and flag = 1 and tanggal
between '2016-07-25' and '2016-07-30'
group by b.OutletCode,tanggal,cash,cc,dc,flash,piutang,reject,disc50,spesial_item,ba,mpm,tf,ul,remarks
) AS tbl2 ON tbl2.outlet = tbl1.customercode AND CAST(tbl2.trnggal AS DATE) = CAST(tbl1.transdate AS DATE)
order by CAST(tbl1.transdate AS DATE) DESC;
I don't have a database installed on this PC but what you're looking for is:
SELECT val1, val2 FROM
(SELECT1_of_your_code AS table1) INNER JOIN
(SELECT2_of_your_code AS table2) ON
table1.x == table2.y

Operand should contain 1 column(s) - in mysql query

I have the following complex query that is giving me an error
Operand should contain 1 column(s)
Can anyone suggest what is wrong
SELECT
t.user_id AS user_id,
t.organisation_id AS organisation_id,
t.firstname AS firstname,
t.surname AS surname,
t.username AS username,
t.year_id AS year_id,
t.form_name AS form_name,
t.House AS House,
rcPoints.total AS milestoneRedeemedCodesTotal,
rcFilteredPoints.total AS redeemedCodesTotalFiltered,
(
COALESCE (rcFilteredPoints.total, 0) - COALESCE (milestoneHistory.total, 0)
) AS redeemedCodesTotalAvailableFiltered,
ABS(
FLOOR(
(
COALESCE (rcFilteredPoints.total, 0) - COALESCE (milestoneHistory.total, 0)
) / 1000
) * 1000
) AS redeemedCodesTotalTowardsMilestone,
ABS(
FLOOR(
(
COALESCE (rcFilteredPoints.total, 0) - COALESCE (milestoneHistory.total, 0)
) / 1000
)
) AS redeemedCodesMilestoneTriggers,
COALESCE (milestoneHistory.total, 0) AS historyTotal
FROM
`myuser` `t`
LEFT JOIN (
SELECT
rc.user_id AS user_id,
SUM(rc.school_points) AS total
FROM
`redeemed_codes` `rc`
INNER JOIN myuser m ON (m.user_id = rc.user_id)
WHERE
(rc.date_redeemed >= 0)
AND (m.organisation_id = 58022)
GROUP BY
rc.user_id
) AS rcPoints ON (rcPoints.user_id = t.user_id)
LEFT JOIN (
SELECT
rc.user_id AS user_id,
SUM(rc.school_points) AS total
FROM
`redeemed_codes` `rc`
INNER JOIN myuser m ON (m.user_id = rc.user_id)
WHERE
(rc.date_redeemed >= 0)
AND (m.organisation_id = 58022)
GROUP BY
rc.user_id
) AS rcFilteredPoints ON (
rcFilteredPoints.user_id = t.user_id
)
LEFT JOIN (
SELECT
mh.user_id AS user_id,
mh.milestone_id AS milestone_id,
MAX(mh.points_when_triggered) AS total
FROM
`milestone_history` `mh`
WHERE
mh.milestone_id = 13
GROUP BY
mh.user_id
) AS milestoneHistory ON (
milestoneHistory.user_id = t.user_id
)
WHERE
(
(
SELECT
COALESCE (count(*), 0)
FROM
milestone_history mha
WHERE
mha.milestone_id = 13
AND mha.user_id = t.user_id
) = 0
)
AND (t.organisation_id = 58022)
AND
(
SELECT * FROM
redeemed_codes t1
WHERE
organisation_id = 1
AND
(
SELECT
sum(school_points)
FROM
redeemed_codes t2
WHERE
t2.redeemed_code_id <= t1.redeemed_code_id
) >= 1000
ORDER BY redeemed_code_id
LIMIT 1
)
GROUP BY
t.user_id
ORDER BY
redeemedCodesMilestoneTriggers DESC
LIMIT 1
Your query might have multiple errors, but this condition in the WHERE clause is definitely suspect and would lead to that error:
AND (SELECT *
FROM redeemed_codes t1
WHERE organisation_id = 1 AND
(SELECT sum(school_points)
FROM redeemed_codes t2
WHERE t2.redeemed_code_id <= t1.redeemed_code_id
) >= 1000
ORDER BY redeemed_code_id
LIMIT 1
)
I have no idea what you are trying to do. Sometimes, the solution is simply EXISTS:
EXISTS (SELECT *
FROM redeemed_codes t1
WHERE organisation_id = 1 AND
(SELECT sum(school_points)
FROM redeemed_codes t2
WHERE t2.redeemed_code_id <= t1.redeemed_code_id
) >= 1000
)

can you please help in tuning the query

This query takes around 45s to 1 min for 25000 records.I need an alternative to case
condition for expirydate field
SELECT a.id,
a.name,
a.lastname,
a.plainpass,
a.email,
a.custom_usertype,
a.custom_registertype,
a.content_state,
a.year,
a.bflag,
a.block,
a.trail_expiry,
a.subscribe_date,
CASE a.custom_usertype
WHEN (5)
THEN
(IF(
(SELECT custom_usertype
FROM skw_users
WHERE id = a.parent_id AND custom_usertype = 11) = 11
AND a.custom_registertype = "subscribed",
(SELECT DATE_FORMAT(prod.expiry_date, "%Y-%m-%d")
FROM skw_product prod
WHERE prod.student_id = a.id
ORDER BY prod.expiry_date DESC
LIMIT 1),
IF(
(SELECT custom_usertype
FROM skw_users
WHERE id = a.parent_id AND custom_usertype = 10) =
10
AND a.custom_registertype = "subscribed",
(SELECT DATE_FORMAT(prod.expiry_date, "%Y-%m-%d")
FROM skw_product prod
WHERE prod.User_id = a.parent_id
ORDER BY prod.expiry_date DESC
LIMIT 1),
(SELECT DATE_FORMAT(trail_expiry, "%Y-%m-%d")
FROM skw_users
WHERE id = a.parent_id))))
WHEN (3)
THEN
(IF(a.custom_registertype = "subscribed",
(SELECT DATE_FORMAT(prod.expiry_date, "%Y-%m-%d")
FROM skw_product prod
WHERE prod.User_id = a.parent_id
ORDER BY prod.expiry_date DESC
LIMIT 1),
(SELECT DATE_FORMAT(trail_expiry, "%Y-%m-%d")
FROM skw_users
WHERE id = a.parent_id)))
ELSE
(IF(a.custom_registertype = "subscribed",
(SELECT DATE_FORMAT(prod.expiry_date, "%Y-%m-%d")
FROM skw_product prod
WHERE prod.User_id = a.id
ORDER BY prod.expiry_date DESC
LIMIT 1),
(SELECT DATE_FORMAT(trail_expiry, "%Y-%m-%d")
FROM skw_users
WHERE id = a.id)))
END
AS expiry_date_n,
CASE a.custom_usertype
WHEN (5)
THEN
(SELECT TRIM(NAME)
FROM skw_users
WHERE id = a.parent_id AND custom_usertype = 10)
WHEN (3)
THEN
(SELECT TRIM(NAME)
FROM skw_users
WHERE id = a.parent_id)
WHEN (10)
THEN
(SELECT TRIM(NAME)
FROM skw_users
WHERE id = a.id AND a.custom_usertype = 10)
END
AS schoolname
FROM `skw_users` AS a
INNER JOIN
skw_user_usergroup_map AS map2
ON map2.user_id = a.id
WHERE map2.group_id = 2
GROUP BY a.id
ORDER BY trim(a.name) ASC
This query takes around 45s to 1 min for 25000 records.I need an alternative to case
condition for expirydate field
Try adding index on Primary Key column that is a.id and the column on which you are applying case that is a.custom_usertype
Hope this will speed up the execution of query :)

query avoding subselect

I have this query and it's very slow. Can i write this query in other way by avoiding subselects for example?
Also i tried adding composite index on
MyIndex(kategorije_id,izdvojen,izdvojen_kad,datum)
but it doesent use it when i explain this query so is there another index that i can use to speed up this query?
SELECT artikli.datum AS brojx, artikli.izdvojen AS i, artikli.izdvojen_kad AS ii, artikli.name
FROM artikli
WHERE artikli.izbrisan =0
AND artikli.prodano !=3
AND artikli.zavrseno =0
AND artikli.od_id !=0
AND kategorije_id
IN ( 18 )
AND (
SELECT count( * )
FROM artikli_polja, polja
WHERE polja.id_kat = artikli.kategorije_id
AND artikli_polja.id_polja = polja.id
AND artikli_polja.id_artikal = artikli.id
AND polja.name = "godiste"
AND artikli_polja.valueInt >= "1993"
) >0
AND (
SELECT count( * )
FROM artikli_polja, polja
WHERE polja.id_kat = artikli.kategorije_id
AND artikli_polja.id_polja = polja.id
AND artikli_polja.id_artikal = artikli.id
AND polja.name = "godiste"
AND artikli_polja.valueInt <= "2000"
) >0
ORDER BY i DESC , ii DESC , brojx DESC
LIMIT 140 , 35
Try this query:
SELECT a.datum AS brojx, a.izdvojen AS i, a.izdvojen_kad AS ii, a.name
FROM artikli a
WHERE a.izbrisan =0
AND a.prodano !=3
AND a.zavrseno =0
AND a.od_id !=0
AND a.kategorije_id = 18
AND EXISTS
(select 'X'
from artikli_polja ap,
JOIN polja p
ON ap.id_polja = p.id AND p.id_kat = a.kategorije_id
AND ap.id_artikal = a.id
AND p.name = 'godiste'
AND ap.valueInt >= 1993 AND ap.valueInt <= 2000
);
Please check.
Try this query -
SELECT a.datum AS brojx, a.izdvojen AS i, a.izdvojen_kad AS ii, a.name FROM artikli a
JOIN artikli_polja ap
ON ap.id_artikal = a.id
JOIN polja p
ON ap.id_polja = p.id AND p.id_kat = a.kategorije_id
WHERE
a.izbrisan =0
AND a.prodano !=3
AND a.zavrseno =0
AND a.od_id !=0
AND kategorije_id = 18
AND p.name = 'godiste'
AND ap.valueInt >= 1993 AND ap.valueInt <= 2000;
I have removed ORDER BY and LIMIT clauses from the query; try to work out this query firstly.