Get max date (last date sale) column against each item no? - sql

I have following SQL Query which return result
of itemno and no of total quantity sale.I want itemdescripton column against each item no as well.ITEMDESC# column in table invitems.
SQL QUERY :
select INITEMS.ITEMNO,(COUNT(INITEMS.ITEMNO)*COUNT(INITEMS.QTY)) 'Item
Sale',INITEMS.ITEMDESC#1 from InvItems INITEMS
INNER JOIN InvHdr HDR ON INITEMS.INVNO=HDR.INVNO
WHERE INITEMS.TYPE='3'
GROUP BY INITEMS.ITEMNO,INITEMS.ITEMDESC#1
I want max date (last date item sale) column in result.Date column in InvHdr table against each InvNo

As explain in the earlier comments, your query does not works because you have different ITEMDESC for the same ITEMNO
This you "gives" you the result that you want
select INITEMS.ITEMNO,
MAX(INITEMS.ITEMDESC#1) AS 'ITEMDESC',
(COUNT(INITEMS.ITEMNO)*COUNT(INITEMS.QTY)) 'Item Sale'
FROM InvItems INITEMS
INNER JOIN InvHdr HDR ON INITEMS.INVNO = HDR.INVNO
WHERE INITEMS.TYPE = '3'
GROUP BY INITEMS.ITEMNO
But you must check why there are such as in your data. You can list out those ITEMNO that is of such case
SELECT ITEMNO
FROM InvItems
GROUP BY ITEMNO
HAVING MAX(ITEMDESC#1) <> MIN(ITEMDESC#1)

Assuming you are working with an SQL Server version higher than 2005 (which is a pretty safe assumption these days), you can use the over clause with aggregating functions, thus potentially eliminating the need for the group by clause (that is potentially since group by will return distinct results for each value (or set of values) that exists in the group by clause - so you might also need to use distinct:
SELECT initems.itemno,
COUNT(initems.itemno) OVER (PARTITION BY initems.itemno)
* SUM(initems.qty) OVER (PARTITION BY initems.itemno)
FROM InvItems AS initems
WHERE initems.type = '3'

Related

Different results in SQL based on what columns I display

I am trying to run a query to gather the total items on hand in our database. However it seems i'm getting incorrect data. I am selecting selecting just the amount field and summing it using joins from separate tables based on certain parameters, however if I display additional fields such as order number, and date all of a sudden im getting different data, even though those fields are being used as filters in the query. Is it because its not in the select statement? If it needs to be in the select statement is it possible to not display them?
Here are the two queries.
-- Items On Hand
select CONVERT(decimal(25, 2), SUM(tw.amount)) as 'Amt'
from [Sales Header] sh
join
(
select *
from TWAllOrders
where [Status] like 'Released'
) tw
on tw.[Order Nb] = sh.No_
join
(
select *
from OnHand
) oh
on tw.No_ = oh.[Item No_]
where sh.[Requested Delivery Date] < getdate()
HAVING SUM(tw.Quantity) <= SUM(oh.Qty)
providing a sum of 21667457.20
and with the added columns
-- Items On Hand
select CONVERT(decimal(25, 2), SUM(tw.amount)) as 'Amt', [Requested Delivery Date], sh.No_, tw.[Status]
from [Sales Header] sh
join
(
select *
from TWAllOrders
where [Status] like 'Released'
) tw
on tw.[Order Nb] = sh.No_
join
(
select *
from OnHand
) oh
on tw.No_ = oh.[Item No_]
where sh.[Requested Delivery Date] < getdate()
group by sh.[Requested Delivery Date], sh.No_, tw.[Status]
HAVING SUM(tw.Quantity) <= SUM(oh.Qty)
order by sh.[Requested Delivery Date] ASC
Providing a sum of 12319998
I'm self taught in SQL so I may be misunderstanding something obvious, thanks for the help.
With no sample data, I am going to have to demonstrate this in principle. In the latter query you have a GROUP BY meaning the scope of the values in the HAVING will differ, and thus the filtering from said HAVING will be different.
Let's take the following sample data:
CREATE TABLE dbo.MyTable (Grp char(1),
Quantity int,
Required int);
INSERT INTO dbo.MyTable (Grp, Quantity, [Required])
VALUES('a',2,7),
('a',14,2),
('b',4, 7),
('b',3,4),
('c',17,5);
Now we'll perform an overly simplified version of your query:
SELECT SUM(Quantity)
FROM dbo.MyTable
HAVING SUM(Quantity) > SUM(Required);
This brings back the value 40; which is the SUM of all the values in Quantity. A value is returned because the total SUM of Required is 25.
Now let's add a GROUP BY like your second query:
SELECT SUM(Quantity)
FROM dbo.MyTable
GROUP BY Grp
HAVING SUM(Quantity) > SUM(Required);
Now we have 2 rows, with the values 16 and 17 giving a total value of 33. That's because the rows where Grp have a value of 'B' are filtered out, as the SUM of Quantity is lower that Required for 'B'.
The same is happening in your data; in the grouped data you have groups where the HAVING condition isn't met, so those rows aren't returned.

SUM all rows in DB2

I am pulling live data from a DB2 server, I am unable to SUM all rows within my query.
On, (HTQTY - HTQTYC) as OnHand, I am trying to SUM all the result for an item.
The item has 66 rows at a total of 8896 pcs. I would like to see the result as 1 row at 8896 pcs.
I have tried different SQL queries with no luck.
select
cjobh.dnname as Customer,
cjobh.dnjob as Job#,
cjobh.dnpart as Kit#,
cjobh.dnqtyr as KitQTY,
methdm.aqmtlp as Component,
methdm.aqqppc as Qty,
cjobh.dnord# as SO#,
cjobh.dnitm# as SOL,
cjobh.dnsdat as Ship_By,
cjobh.dnodat as Released_On,
cjobop.ehodes as Kind,
htbinl as Location,
(HTQTY - HTQTYC) as OnHand,
(DNQTYR*AQQPPC) as Needed
from CJOBH
left join methdm on aqpart = dnpart
left join cjobop on ehjob# = dnjob
left join seri on htpart = aqmtlp
where dnstat <> 'C'
and dnpart like '%KIT%'
and ehseq# = '100'
and ehlin# = '1'
and HTPLNT = 'GC'
and HTSTS = 'A'
Try
with cte as (
<put your query here>
)
SELECT sum(OnHand)
FROM cte
Edit:
If you need to keeep the other columns try adding an additional column like this
, sum(HTQTY - HTQTYC) over ()
Because you had no group by specified an empty brackets after the OVER keyword is enough. You could also add an partition by clause within the brackets if you need addtional grouping

How to get the sum of transaction amount happened in one date?

I am trying to write a query that will give me transaction amount sum happened in one date. The problem is , when I added column date in my query, I get individual values not their sum. The requirement for this query is to have one entry for each merchant but i am getting multiple rows for one merchant.
SELECT SUBSTR(m.MERCHANTLASTNAME, 1, 36) Name1,
m.MERCHANTBANKBSB MerchantAccbsb,
m.MERCHANTBANKACCNR Merchant_act,
m.MERCHANTID merchantid,
t.transactiondate date1,
sum(t.TRANSACTIONAMOUNT) as total
FROM fss_merchant m
JOIN fss_terminal term
ON m.MERCHANTID = term.MERCHANTID
JOIN FSS_DAILY_TRANSACTION t
ON term.TERMINALID = t.TERMINALID
group by t.transactiondate, SUBSTR(m.MERCHANTLASTNAME, 1, 36), m.MERCHANTID, m.MERCHANTBANKBSB, m.MERCHANTBANKACCNR,
m.MERCHANTLASTNAME
Output of my query:
I want to get one entry per each merchant with the sum of transaction amount in one day, not multiple rows of transaction in that day.
You can calculate the total amount in different inner query with the truncated date and join it with FSS_MERCHANT table so that issues described by #SatishSK and #mangusta is taken care.
You can use the following query:
SELECT
SUBSTR(M.MERCHANTLASTNAME, 1, 36) NAME1,
M.MERCHANTBANKBSB MERCHANTACCBSB,
M.MERCHANTBANKACCNR MERCHANT_ACT,
M.MERCHANTID MERCHANTID,
M_DATA.TRANSACTIONDATE DATE1,
M_DATA.TOTAL AS TOTAL
FROM
FSS_MERCHANT M
INNER JOIN (
SELECT
TERM.MERCHANTID MERCHANTID,
TRUNC(T.TRANSACTIONDATE) TRANSACTIONDATE,
SUM(T.TRANSACTIONAMOUNT) AS TOTAL
FROM
FSS_TERMINAL TERM
JOIN FSS_DAILY_TRANSACTION T ON TERM.TERMINALID = T.TERMINALID
GROUP BY
TERM.MERCHANTID,
TRUNC(T.TRANSACTIONDATE)
) M_DATA ON ( M.MERCHANTID = M_DATA.MERCHANTID );
Good luck!!
t.transactiondate column might contain date+time values. Use TRUNC(t.transactiondate) where you are using just t.transactiondate. You will get sum(transaction amount) "Date-wise" for each merchant.
OR
Filter out rows based on "Date" value in WHERE clause to retrieve data pertaining to a specific date.
Probably the reason is that you have included both m.MERCHANTLASTNAME and SUBSTR(m.MERCHANTLASTNAME,1,36) into the group by clause.
In case if there are entries with same SUBSTR(m.MERCHANTLASTNAME,1,36) but different m.MERCHANTLASTNAME, this is going to yield duplicates. You need to remove m.MERCHANTLASTNAME from group by clause

Unpivot date columns to a single column of a complex query in Oracle

Hi guys, I am stuck with a stubborn problem which I am unable to solve. Am trying to compile a report wherein all the dates coming from different tables would need to come into a single date field in the report. Ofcourse, the max or the most recent date from all these date columns needs to be added to the single date column for the report. I have multiple users of multiple branches/courses for whom the report would be generated.
There are multiple blogs and the latest date w.r.t to the blogtitle needs to be grouped, i.e. max(date_value) from the six date columns should give the greatest or latest date for that blogtitle.
Expected Result:
select u.batch_uid as ext_person_key, u.user_id, cm.batch_uid as ext_crs_key, cm.crs_id, ir.role_id as
insti_role, (CASE when b.JOURNAL_IND = 'N' then
'BLOG' else 'JOURNAL' end) as item_type, gm.title as item_name, gm.disp_title as ITEM_DISP_NAME, be.blog_pk1 as be_blogPk1, bc.blog_entry_pk1 as bc_blog_entry_pk1,bc.pk1,
b.ENTRY_mod_DATE as b_ENTRY_mod_DATE ,b.CMT_mod_DATE as BlogCmtModDate, be.CMT_mod_DATE as be_cmnt_mod_Date,
b.UPDATE_DATE as BlogUpDate, be.UPDATE_DATE as be_UPDATE_DATE,
bc.creation_date as bc_creation_date,
be.CREATOR_USER_ID as be_CREATOR_USER_ID , bc.creator_user_id as bc_creator_user_id,
b.TITLE as BlogTitle, be.TITLE as be_TITLE,
be.DESCRIPTION as be_DESCRIPTION, bc.DESCRIPTION as bc_DESCRIPTION
FROM users u
INNER JOIN insti_roles ir on u.insti_roles_pk1 = ir.pk1
INNER JOIN crs_users cu ON u.pk1 = cu.users_pk1
INNER JOIN crs_mast cm on cu.crsmast_pk1 = cm.pk1
INNER JOIN blogs b on b.crsmast_pk1 = cm.pk1
INNER JOIN blog_entry be on b.pk1=be.blog_pk1 AND be.creator_user_id = cu.pk1
LEFT JOIN blog_CMT bc on be.pk1=bc.blog_entry_pk1 and bc.CREATOR_USER_ID=cu.pk1
JOIN gradeledger_mast gm ON gm.crsmast_pk1 = cm.pk1 and b.grade_handler = gm.linkId
WHERE cu.ROLE='S' AND BE.STATUS='2' AND B.ALLOW_GRADING='Y' AND u.row_status='0'
AND u.available_ind ='Y' and cm.row_status='0' and and u.batch_uid='userA_157'
I am getting a resultset for the above query with multiple date columns which I want > > to input into a single columnn. The dates have to be the most recent, i.e. max of the dates in the date columns.
I have successfully done the Unpivot by using a view to store the above
resultset and put all the dates in one column. However, I do not
want to use a view or a table to store the resultset and then do
Unipivot simply because I cannot keep creating views for every user
one would query for.
The max(date_value) from the date columns need to be put in one single column. They are as follows:
* 1) b.entry_mod_date, 2) b.cmt_mod_date ,3) be.cmt_mod_date , 4) b.update_Date ,5) be.update_date, 6) bc.creation_date *
Apologies that I could not provide the desc of all the tables and the
fields being used.
Any help to get the above mentioned max of the dates from these
multiple date columns into a single column without using a view or a
table would be greatly appreciated.*
It is not clear what results you want, but the easiest solution is to use greatest().
with t as (
YOURQUERYHERE
)
select t.*,
greatest(entry_mod_date, cmt_mod_date, cmt_mod_date, update_Date,
update_date, bc.creation_date
) as greatestdate
from t;
select <columns>,
case
when greatest (b_ENTRY_mod_DATE) >= greatest (BlogCmtModDate) and greatest(b_ENTRY_mod_DATE) >= greatest(BlogUpDate)
then greatest( b_ENTRY_mod_DATE )
--<same implementation to compare each time BlogCmtModDate and BlogUpDate separately to get the greatest then 'date'>
,<columns>
FROM table
<rest of the query>
UNION ALL
Select <columns>,
case
when greatest (be_cmnt_mod_Date) >= greatest (be_UPDATE_DATE)
then greatest( be_cmnt_mod_Date )
when greatest (be_UPDATE_DATE) >= greatest (be_cmnt_mod_Date)
then greatest( be_UPDATE_DATE )
,<columns>
FROM table
<rest of the query>
UNION ALL
Select <columns>,
GREATEST(bc_creation_date)
,<columns>
FROM table
<rest of the query>

SQL: Using UNION

Here is the question and database info.
Use the UNION command to prepare a full statement for customer 'C001' - it should be laid out as follows. (Note that the values shown below are not correct.) You may be able to use '' or NULL for blank values - if necessary use 0.
Here is a link to the webpage with the database info. http://sqlzoo.net/5_0.htm or see the image below.
Here is what I have tried:
SELECT sdate AS LineDate, "delivery" AS LEGEND, price*quantity AS Total,"" AS Amount
FROM shipped
JOIN product ON (shipped.product=product.id)
WHERE badguy='C001'
UNION
SELECT rdate,notes, "",receipt.amount
FROM receipt
WHERE badguy='C001'
Here is what I get back:
Wrong Answer. The correct answer has 5 row(s).
The amounts don't seem right in the amount column and I can't figure out how to order the data by the date since it is using two different date columns (sdate and rdate which are UNIONED).
Looks like the data in the example is being aggregated by date and charge type using group by, that's why you are getting too many rows.
Also, you can sort by the alias of the column (LineDate) and the order by clause will apply to all the rows in the union.
SELECT sdate AS LineDate, "delivery" AS LEGEND, SUM(price*quantity) AS Total,"" AS Amount
FROM shipped
JOIN product ON (shipped.product=product.id)
WHERE badguy='C001'
GROUP BY sdate
UNION
SELECT rdate, notes, "",receipt.amount
FROM receipt
WHERE badguy='C001'
ORDER BY LineDate
It's usually easiest to develop each part of the union separately. Pay attention to the use of "null" to separate the monetary columns. The first select gets to name the columns.
select s.sdate as tr_date, 'Delivery' as type, sum((s.quantity * p.price)) as extended_price, null as amount
from shipped s
inner join product p on p.id = s.product
where badguy = 'C001'
group by s.sdate
union all
select rdate, notes, null, sum(amount)
from receipt
where badguy = 'C001'
group by rdate, notes
order by tr_date