How to data show Data Row Column in Postgresql? - postgresql

Here is my data and query. I want row data show in columns... Can someone help me to modify the query? I am using PostgreSQL queries.
select
ss.name, ip.product_name, ssr.quantity
from
services_servicerecipe ssr
inner join
services_service ss on ssr.service_id = ss.id
inner join
inventory_product ip on ssr.product_id = ip.id
order by
ss.name
Output:
Service_name | Product_name | Quantity
-------------+------------------+-----------
Balayage | 7.3-revlon | 2
Balayage | 701-revlon | 1
I want it to look like this
Service_name | Product_name | Quantity | Product_name | Quantity
-------------+-------------------+--------------+------------------+----------
Balayage | 7.3-revlon | 2 | 701-revlon | 1

Here is a pivot option, using ROW_NUMBER:
with cte as (
select ss.name, ip.product_name, ssr.quantity,
row_number() over (partition by ss.name order by ip.product_name) rn
from services_servicerecipe ssr
inner join services_service ss on ssr.service_id = ss.id
inner join inventory_product ip on ssr.product_id = ip.id
)
select
name,
max(case when rn = 1 then product_name end) as product1,
max(case when rn = 1 then quantity end) as quantity1,
max(case when rn = 2 then product_name end) as product2,
max(case when rn = 2 then quantity end) as quantity2
from cte
group by name;

Related

Merge rows postgres and replace values with latest when not null

I have a table that looks like this:
I am looking for a way to merge the columns on organizations_core_id so that the query returns this:
organization_core_id, slug, name
1, dolphin, Dolphin v2
2, sea-horse-club, Sea Horse
How can I merge these columns and replace the latest value?
First group by organization_core_id to get the ids of the rows with the last not null values for slug and name and then join to the table:
select
t.organization_core_id,
t1.slug,
t2.name
from (
select
organization_core_id,
max(case when slug is not null then id end) slugid,
max(case when name is not null then id end) nameid
from tablename
group by organization_core_id
) t
left join tablename t1 on t1.id = t.slugid
left join tablename t2 on t2.id = t.nameid
See the demo.
Results:
> organization_core_id | slug | name
> -------------------: | :------------- | :---------
> 1 | dolphin | Dolphin v2
> 2 | sea-horse-club | Sea Horse

how can i calculate sum of PaidAmount that is made between two dates

I have 3 tables which are Accounts, Payments, Statements. Table Accounts have all the accounts, table Payments have all the payments made to the account, and table Statements have all the statement data for the accounts.
Accounts
AccountID | DateOfDeath |
1001 | 2014-03-10 |
Payments
AccountID | PaidAmount | PaymentDate
1001 | 80.27 | 2014-07-09
1001 | 80.27 | 2014-06-10
1001 | 80.27 | 2014-05-12
1001 | 80.27 | 2014-04-13
1001 | 80.27 | 2014-03-15
1001 | 80.27 | 2014-02-14
Statements
AccountID | Balance | StatementDate
1001 | 0.00 | 2014-03-28
1001 | 1909.31 | 2014-02-25
I need to know the sum of PaidAmount (table Payments) in Payments table which is between the StatementDate (table Statements) of 2014-03-28 and 2014-02-25. The sum of the PaidAmount should have been 80.27 but I am getting 321.08. Can anyone tell me what I am doing wrong or how can I write the query in a better way?
here is what I have so far
create table #temp1
(
AccountID Numeric(9, 0)
, DateOfDeath date
, StatementDate date
, Balance numeric(17,2)
)
insert into #temp1
(
AccountID, DateOfDeath, StatementDate, Balance
)
select a.AccountID
,DateofDeath
,StatementDate
,Balance
from Accounts a
inner join Statements b on a.accountID = b.accountID
where StatementDate in (select top 1 statementdate
from Statements
where AccountID = a.AccountID
and StatementDate >= DateOfDeath
order by StatementDate)
Order By a.AccountID, StatementDate
create table #temp2
(
AccountId Numeric(9,0)
, PaidAmount Numeric(10, 2)
, PaymentDate date
)
select a.accountid, sum(a.Paidamount), max(a.PaymentDate)
from tblCreditDefenseInceptionToDateBenefit a
inner join #temp1 b on a.accountid = b.accountid
where a.paymentdate <= (select top 1 StatementDate from Statements
where AccountID = a.accountid
and statementdate >= b.dateofdeath
order by StatementDate desc)
and a.paymentdate > (select top 1 StatementDate from Statements
where AccountID = a.accountid
and statementdate < b.dateofdeath
order by StatementDate desc)
group by a.accountid
order by a.accountid desc
select * from #temp2
drop table #temp1
drop table #temp2
you can go about it a few ways
Create table #accounts
(AccountID int, Date_Death date)
insert into #accounts
(accountID, Date_death)
values
('1001', '03/10/2014')
Create Table #payments
(AccountID int, paidamt decimal(6,2), paymentdt date)
insert into #payments
(AccountID , paidamt, paymentdt)
values
('1001', '80.27','07/09/2014'),
('1001', '80.27','06/10/2014'),
('1001', '80.27','05/12/2014'),
('1001', '80.27','04/13/2014'),
('1001', '80.27','03/15/2014'),
('1001', '80.27','02/14/2014')
;
with cte as (
select
Accountid,
case when paymentdt between '02/25/2014'and '03/28/2014' then (paidamt) else null end as paidamt
from
#payments
)
Select
accountid,
SUM(paidamt)
from cte
group by
AccountID
or
put it in the where clause instead of doing a case statement, really depends onyour style
select
accountid,
sum(paidamt)paidamt
from
#payments
where paymentdate >= '02/25/2014'
and paymentdate <= '03/282014'
or
if you want to use the statement table dates as parameters
with cte as
(
select
a.AccountID,
case when a.paymentdt between b.min_dt and b.max_dt then a.paidamt else null end as 'pdamt'
from
#payments as a
inner join
(select accountid, MIN(statementdt)min_dt, MAX(statementdt)max_dt from #statement group by accountid) as b on b.accountid = a.AccountID
)
select
AccountID,
SUM(pdamt) as 'Paid Amount'
from
cte
group by
AccountID
again, could be added in where clase if you dontwant to do case staements

Using CASE with GROUP BY

I have the following query in T-SQL:
SELECT dbo.table2.device,
dbo.table2.CREATETIME AS create_time,
CASE WHEN dbo.table1.ACTIONID = 1
THEN dbo.table1.startstop
END AS start_time,
CASE WHEN dbo.table1.ACTIONID = 2
THEN dbo.table1.startstop
END AS stop_time,
dbo.table2.collect_time
FROM dbo.table2
JOIN dbo.table1 ON dbo.table1.CREATETIME = dbo.table2.CREATETIME;
...which gives me a result table with several rows, each a duplicate with once the start- once the end- time (sql time - shortened for simplicity) - the other being NULL - e.g.:
device | create_time | start_time | stop_time | collect_time
1 | 0000001 | 0000001 | NULL | 0000001
1 | 0000001 | NULL | 0000002 | 0000001
I want to group these two rows (with create_time as ID) so I get them into one.... Thanks!
You can aggregate (SUM) these columns:
SELECT dbo.table2.device,
dbo.table2.CREATETIME AS create_time,
SUM(CASE WHEN dbo.table1.ACTIONID = 1
THEN dbo.table1.startstop ELSE 0
END) AS start_time,
SUM(CASE WHEN dbo.table1.ACTIONID = 2
THEN dbo.table1.startstop ELSE 0
END) AS stop_time,
dbo.table2.collect_time
FROM dbo.table2
JOIN dbo.table1 ON dbo.table1.CREATETIME = dbo.table2.CREATETIME
GROUP BY dbo.table2.device, dbo.table2.CREATETIME, dbo.table2.collect_time;
Also I suppose using subquery would work out as well
SELECT
X.Device
,sum(X.start_time)
,sum(X.stop_time)
,X.collect_time
from(
SELECT dbo.table2.device,
dbo.table2.CREATETIME AS create_time,
CASE WHEN dbo.table1.ACTIONID = 1
THEN dbo.table1.startstop
END AS start_time,
CASE WHEN dbo.table1.ACTIONID = 2
THEN dbo.table1.startstop
END AS stop_time,
dbo.table2.collect_time
FROM dbo.table2
JOIN dbo.table1 ON dbo.table1.CREATETIME = dbo.table2.CREATETIME) AS X
group by
X.Device, X.collect_time

How to count rows in SQL Server with range distinct to count the record within range

SELECT Distinct
m_KioskInformationHdr.kioskID,m_KioskInformationHdr.agency,
m_KioskInformationHdr.kioskIP,
COUNT(distinct m_KioskInformationHdr.KioskID) as NoDT
from
m_KioskInformationHdr
inner join
t_KioskStatus ON t_kioskStatus.kioskID = m_KioskInformationHdr.kioskID
where
t_KioskStatus.IsOpen = 1
and DatePost between '2014-01-20 00:00:00' and '2014-01-21 23:59:59'
group by
t_KioskStatus.DatePost, m_KioskInformationHdr.kioskID,
m_KioskInformationHdr.kioskIP, m_KioskInformationHdr.agency
I want this output:
01254878 | PHilippines,Pasig | 192.168.2.8 | 2
This is my current output:
01254878 | PHilippines,Pasig | 192.168.2.8 | 1
01254878 | PHilippines,Pasig | 192.168.2.8 | 1
How can I do this query?
Select
mk.kioskID, mk.agency, mk.kioskIP, count(mk.kioskID) as NoDT
from
(
SELECT
m_KioskInformationHdr.kioskID,m_KioskInformationHdr.agency,m_KioskInformationHdr.kioskIP
from
m_KioskInformationHdr
inner join
t_KioskStatus ON t_kioskStatus.kioskID = m_KioskInformationHdr.kioskID
where
t_KioskStatus.IsOpen = 1
and DatePost between '2014-01-20 00:00:00' and '2014-01-21 23:59:59') mk
group by
mk.DatePost, mk.kioskID,
mk.kioskIP, mk.agency

SQL Selecting Maximum Based on Minor-Major scheme

I am trying to create a query that will select a DISTINCT line, select using a revision Minor / Major scheme. Below is an example table:
Serial Number | RevMajor | RevMinor
-----------------------------------
AQ155 | 1 | 1
AQ155 | 1 | 2
AQ155 | 1 | 1
AQ155 | 1 | 7
AQ155 | 2 | 1 <---------
JR2709 | 1 | 7
JR2709 | 2 | 2 <---------
How can I write a query in T-SQL 2008 that will select only the two highlighted lines, the "Newest Revision"?
Thanks in advance!
You could
select * from (
select *, row_number() over (partition by [Serial Number] order by RevMajor desc, RevMinor desc) VersionRank
from table
) T
where VersionRank = 1
select [serial number], revmajor, revminor
from table1
where revMajor = (select max(revmajor) from table1)
another way to do this could be:
select [serial number], revmajor, revminor
from table1 a
inner join ( select max(revMajor) from table1 ) b on a.revmajor = b.revmajor
Another way if you know there are only 2 rows:
select top 2 [serial number], revmajor, revminor
from table1 a
order by revmajor desc, revminor desc