How to inner join with other select? - postgresql-13

How to inner join with other select?
in my case I have to get the max from 'b' and inner join with a.pid and position of the 'a'
select a.pid, max(position) mp from tickets a, jsonb_array_elements(a.actions) with
ordinality arr(item, position)
inner join
(select aa.pid, position from tickets aa, jsonb_array_elements(aa.actions) with
ordinality arr(item, position)) b
on a.pid = b.pid and a.mp=b.position
group by a.pid

Related

SQL Server : left join - check for right table column value is null

I have a query as follows:
select --this select should always give me 1 record
tbl1.Id, tbl1.Name, tbl1.Address, tbl2.relNo,
CASE WHEN tbl3.Comments IS NOT NULL THEN 1 ELSE 0 END AS 'Required'
from
table1 tbl1
inner join
table2 tbl2 on tbl2.Id = tbl1.Id
left join -- This left join table gives me 5 records for one instance
(select
R.Id, C.Comments
from
tblC C
inner join
tblR R on R.Id = C.id) tbl3 on tbl3.Id = tbl2.Id
I want to write a CASE statement on the rows my left join is giving to check for null value as above and my final select query always return only 1 row. Is there a way to check if all five Comments Column values from my left join be checked for NULLs in the above query?
I would take a shortcut an use a COUNT() OVER PARTITION
CASE WHEN COUNT(*) OVER (PARTITION BY tbl3.Id) =0 THEN 0 ELSE 1 END AS 'Required'
You would have to DISTINCT your output above. Another option would be to GROUP BY and filter in the HAVING clause.
select --this select should always give me 1 record
tbl1.Id, tbl1.Name, tbl1.Address, tbl2.relNo
From table1 tbl1
inner join table2 tbl2 on tbl2.Id = tbl1.Id
left join (-- This left join table gives me 5 records for one instance
SELECT R.Id,
C.Comments
FROM tblC C
INNER JOIN tblR R on R.Id = C.id
) tbl3 on tbl3.Id = tbl2.Id
GROUP BY
Id, Name, Address, relNo
HAVING
COUNT(*) = 5
Is this what you're looking for?
(CASE WHEN (select count(tbl3.id) FROM tbl3 WHERE tbl3.Comments IS NULL) then 1 else 0 end) as 'RequiredVal'
select --this select should always give me 1 record
tbl1.Id, tbl1.Name, tbl1.Address, tbl2.relNo,
CASE WHEN tbl3.Comments IS NOT NULL THEN 1 ELSE 0 END AS 'Required'
, (CASE WHEN (select count(tbl3.id) FROM tbl3 WHERE tbl3.Comments IS NULL) then 1 else 0 end) as 'RequiredVal'
From table1 tbl1
inner join table2 tbl2 on tbl2.Id = tbl1.Id
left join (-- This left join table gives me 5 records for one instance
SELECT R.Id,
C.Comments
FROM tblC C
INNER JOIN tblR R on R.Id = C.id
) tbl3 on tbl3.Id = tbl2.Id

I'm getting error cannot perform an aggregate function on an expression containing an aggregate or a subquery

SELECT sum(sum(DATEDIFF(DAY,LeaveBreakup.StartDate,LeaveBreakup.EndDate)+1)) AS totalNoOfDays,
LeaveApplication.Id,
LeaveBreakup.StartDate,
LeaveBreakup.EndDate,
LeaveApplication.ReasonForLeave,
LeaveApplication.ProcessorComment,
Team.Name,
LeaveTypeDetail.Name
FROM LeaveApplication
INNER JOIN Employee ON LeaveApplication.Employee=Employee.Id
INNER JOIN Team ON Employee.Team=Team.Id
INNER JOIN LeaveBreakup ON LeaveApplication.Id=LeaveBreakup.LeaveApplication
INNER JOIN LeaveTypeDetail ON LeaveBreakup.LeaveType=LeaveTypeDetail.LeaveType
WHERE Employee.Team=5
AND LeaveStatus!=0
AND LeaveBreakup.StartDate BETWEEN '01-01-2016' AND '01-31-2016'
AND LeaveBreakup.WhichHalf=0
GROUP BY LeaveApplication.Id,
LeaveBreakup.StartDate,
LeaveBreakup.EndDate,
LeaveApplication.ReasonForLeave,
LeaveApplication.ProcessorComment,
Team.Name,
LeaveTypeDetail.Name
ORDER BY LeaveBreakup.StartDate
Try something like this.
SELECT sum(totalNoOfDays) as total,
a.Id,
a.StartDate,
a.EndDate,
a.ReasonForLeave,
a.ProcessorComment,
a.Name,
a.Name
from
select
(
select sum(DATEDIFF(DAY,LeaveBreakup.StartDate,LeaveBreakup.EndDate)+1) AS totalNoOfDays,
LeaveApplication.Id,
LeaveBreakup.StartDate,
LeaveBreakup.EndDate,
LeaveApplication.ReasonForLeave,
LeaveApplication.ProcessorComment,
Team.Name,
LeaveTypeDetail.Name
FROM LeaveApplication
INNER JOIN Employee ON LeaveApplication.Employee=Employee.Id
INNER JOIN Team ON Employee.Team=Team.Id
INNER JOIN LeaveBreakup ON LeaveApplication.Id=LeaveBreakup.LeaveApplication
INNER JOIN LeaveTypeDetail ON LeaveBreakup.LeaveType=LeaveTypeDetail.LeaveType
WHERE Employee.Team=5
AND LeaveStatus!=0
AND LeaveBreakup.StartDate BETWEEN '01-01-2016' AND '01-31-2016'
AND LeaveBreakup.WhichHalf=0
GROUP BY LeaveApplication.Id,
LeaveBreakup.StartDate,
LeaveBreakup.EndDate,
LeaveApplication.ReasonForLeave,
LeaveApplication.ProcessorComment,
Team.Name,
LeaveTypeDetail.Name
)a
group by
a.Id,
a.StartDate,
a.EndDate,
a.ReasonForLeave,
a.ProcessorComment,
a.Name,
a.Name
ORDER BY a.StartDate

TSQL: SUM not working like i thought it would

I have the following query:
SELECT
a.Name,
ISNULL(CAST(sum((b.qty * b.unit_rate)* b.Eng_RPQ )/100 AS DECIMAL(8,1)),0) AS [EngHours],
SUM(BR.BlendedRate)
FROM
Activity_Details b
INNER JOIN
Activity c on b.activity_id = c.id
INNER JOIN
Project p on p.id = c.project_id
RIGHT OUTER JOIN
Discipline a on c.discipline_id = a.id
INNER JOIN
(SELECT
a.Name, c.id,
CAST(f.POH * (d.HourlyRate * (1-(r.Discount/100))/100) AS DECIMAL(8,2)) AS BlendedRate
FROM
Activity_Details b
INNER JOIN
Activity c on b.activity_id = c.id
INNER JOIN
Team f on f.activity_id = c.id
INNER JOIN
SOF_Details d on d.id = f.sof_detail_id
INNER JOIN
Project p on p.id = c.project_id
INNER JOIN
Rate r on r.projectid = p.id
INNER JOIN
Teammate_Type tt on tt.id = f.team_type_id
RIGHT OUTER JOIN
Discipline a on c.discipline_id = a.id
GROUP BY
a.Name, c.id, f.POH, d.HourlyRate, r.Discount) AS BR ON BR.id = c.id
GROUP BY
a.Name
ORDER BY
a.Name
Which yields:
Name EngHours BlendedRate
Architechtural 80.8 38.48
Architechtural 80.8 55.33
Architechtural 80.8 55.40
I want to SUM this BlendedRate and ROUND it but if i try SUM(BR.BlendedRate) to the SELECT and remove the BR.BlendedRate in the GROUP BY
I get:
Name EngHours BlendedRate
Architechtural 242.3 895.26
I was expecting BlendedRate to equal 149.21
Any idea what i am doing wrong?
unable to comment due to reputation. It is a crude solution, but your code is returning duplicated (seemingly 6) records. The code should be fixed elsewhere, but without sample data it is difficult. In the mean time a crude solution would be to add a distinct clause to the sum function
SUM( DISTINCT BR.BlendedRate)

SQL query to fetch repeat column values within time frame

I have an eCommerce website where I am getting lot of fraud orders.. I'd like to pull out those Order_No.
Here is my query
SELECT
O.Order_No, O.Customer_ID, O.DateOrdered, O.IPAddress,
C.FirstName, C.LastName, CD.nameoncard
FROM
Order_No O
INNER JOIN
CardData CD ON O.card_id = CD.id
INNER JOIN
Customers C ON O.customer_id = C.customer_id
ORDER BY
O.order_no desc
Here's the criteria I want to follow:
If the customer_id repeats more than once in 6hrs
If the IPAddress repeats more than once in 6hrs
If the Lastname is NOT found in Nameoncard
Can someone help please?
can you try this
WITH Tmp (Order_No, Customer_id, DateOrdered, IPAddress, FirstName, LastName, NameOnCard)
AS
(
SELECT Ord.Order_No, Ord.Customer_Id, Ord.DateOrdered, Ord.IPAddress,
Cust.FirstName, Cust.LastName, CustData.NameOnCard
FROM Order_No Ord
INNER JOIN Customers Cust
ON
Cust.Customer_Id = Ord.Customer_Id
INNER JOIN
CardData CustData
ON CustData.Id = Ord.Card_Id
)
SELECT DISTINCT a.*
FROM Tmp a
INNER JOIN Tmp b
ON a.Order_No <> b.Order_No
AND a.Customer_Id = b.Customer_Id
WHERE DATEDIFF(hour, a.DateOrdered, b.DateOrdered) >= 6
UNION
SELECT DISTINCT c.*
FROM Tmp c
INNER JOIN Tmp d
ON c.Order_No <> d.Order_No
AND c.IPAddress = d.IPAddress
WHERE DATEDIFF(hour, c.DateOrdered, d.DateOrdered) >= 6
UNION
SELECT DISTINCT e.*
FROM Tmp e
WHERE ISNULL(e.NameOnCard,'') = ''
here is the query:
select * from
(
select b.order_no,b.dateordered,a.customer_id, C.FirstName, C.LastName, cd.nameoncard from order_no as a
left join order_no as b on a.customer_id=b.customer_id
inner join carddata as cd on b.customer_id=cd.customer_id
INNER JOIN Customers C ON b.customer_id = C.customer_id
where a.order_no < b.order_no
and datediff(hour,a.dateordered,b.dateordered) between 0 and 6
union
select b.order_no,b.dateordered,a.customer_id, C.FirstName, C.LastName, cd.nameoncard from order_no as a
left join order_no as b on a.IPAddress=b.IPAddress
inner join carddata as cd on b.customer_id=cd.customer_id
INNER JOIN Customers C ON b.customer_id = C.customer_id
where a.order_no < b.order_no
and datediff(hour,a.dateordered,b.dateordered) between 0 and 6
union
select a.order_no,a.dateordered,a.customer_id, C.FirstName, C.LastName, cd.nameoncard from order_no as a
inner join carddata as cd on a.customer_id=cd.customer_id
INNER JOIN Customers C ON a.customer_id = C.customer_id
where charindex(C.LastName,cd.nameoncard) = 0
) as abc

multiple count in a sql query

i need a report from a database where i need the final result like
Number of Male, Number of Female, showing against city and finally against State.
I started off with something like.
SELECT p.StateName, d.CityName,
count(api.Gender) as Gender
FROM dbo.Application_Personal_information as api INNER JOIN
dbo.state as p ON api.State = p.ID INNER JOIN
dbo.City as d ON api.City= d.ID
group by p.StateName, d.CityName
when i do this
SELECT p.StateName, d.CityName,
count(api.Gender = 'Male) as Male,
count(api.Gender = 'Female) as Female,
FROM dbo.Application_Personal_information as api INNER JOIN
dbo.state as p ON api.State = p.ID INNER JOIN
dbo.City as d ON api.City= d.ID
group by p.StateName, d.CityName
it give's me error.
incorrect syntax near =.
i also tried with select statement
COUNT(select api.Gender from api where api.Gender ='Male') as Male,
But it is also not working.
...
Any idea?
SELECT
p.StateName, d.CityName,
sum(case when Gender ='Male' then 1 else 0 end ) as Male_count,
sum(case when Gender ='Female' then 1 else 0 end ) as Female_count
FROM
dbo.Application_Personal_information as api INNER JOIN
dbo.state as p ON api.State = p.ID INNER JOIN
dbo.City as d ON api.City= d.ID
group by
p.StateName, d.CityName
You could try the PIVOT function if you are using SQL Server 2005 or later:
WITH CTE AS
( SELECT p.StateName,
d.CityName,
api.Gender
FROM dbo.Application_Personal_information as api
INNER JOIN dbo.state as p
ON api.State = p.ID
INNER JOIN dbo.City as d
ON api.City= d.ID
)
SELECT *
FROM CTE
PIVOT
( COUNT(Gender)
FOR Gender IN ([Male], [Female])
) pvt

Resources