Inner join same table syntax error - sql

I'm trying to run an inner join between this same table. What is wrong with my syntax?
(SELECT user_key, bill_number, MAX(payment_date) AS payment_date
FROM billpayment) bpt
INNER JOIN (SELECT * FROM billpayment) bp
ON bp.user_key=bpt.user_key
AND bp.bill_number=bpt.bill_number
AND bp.payment_date=bpt.payment_date
GROUP BY user_key, bill_number;
It says that the sql command is not properly ended at the parenthesis in 'billpayment)'

SELECT
user_key,
bill_number,
MAX(payment_date) AS payment_date
FROM billpayment bpt
INNER JOIN billpayment bp
ON bp.user_key=bpt.user_key
AND bp.bill_number=bpt.bill_number AND bp.payment_date=bpt.payment_date
GROUP BY
user_key, bill_number
;

On Oracle Try this:
SELECT *
FROM (SELECT user_key, bill_number, MAX (payment_date) AS payment_date FROM billpayment) bpt
INNER JOIN billpayment bp
ON bp.user_key = bpt.user_key AND bp.bill_number = bpt.bill_number AND bp.payment_date = bpt.payment_date
GROUP BY user_key, bill_number;
Can't test it without the table structure.

How about just using analytic functions?
select bp.*,
max(bp.paymentdate) over (partition by user_key, bill_number) as max_payment_date
from billpayment
If you want the fields on the max payment date:
select bp.*
from (select bp.*,
max(bp.paymentdate) over (partition by user_key, bill_number) as max_paymentdate
from billpayment
) bp
where paymentdate = max_paymentdate;

On mySQL, you can try something like:
SELECT bpt.user_key, bpt.bill_number, MAX(bpt.payment_date) AS payment_date
FROM billpayment bpt
INNER JOIN (SELECT * FROM billpayment) bp
ON bp.user_key=bpt.user_key
AND bp.bill_number=bpt.bill_number
AND bp.payment_date=bpt.payment_date
GROUP BY bpt.user_key, bpt.bill_number;

Related

Subquery within scalar subquery fails with error ORA-00936 Missing Expression

This is the query that does not work:
SELECT distinct ord.DateOrdered
, (SELECT docno
FROM th_mm_c_orderline_history
WHERE th_mm_c_orderline_history_id
in (SELECT max(th_mm_c_orderline_history_id)
FROM th_mm_c_orderline_history
GROUP BY c_orderline_id )
order by docno,c_orderline_id) as docno
FROM c_order ord
INNER JOIN c_orderline on c_orderline.c_order_id = ord.c_order_id
INNER JOIN th_mm_c_orderline_history
on th_mm_c_orderline_history.c_order_id=ord.c_order_id
It is throwing me ORA-00936 Missing expression error
This query works fine:
SELECT docno
FROM th_mm_c_orderline_history
WHERE th_mm_c_orderline_history_id
in (SELECT max(th_mm_c_orderline_history_id)
FROM th_mm_c_orderline_history
GROUP BY c_orderline_id )
order by docno,c_orderline_id as docno
Just remove the order by clause from the inline select. You can not use orde by clause there. You can use it in the outer select if you need it...This is how you can do all three of them without the error:
SELECT distinct ord.DateOrdered
, (SELECT docno FROM th_mm_c_orderline_history
WHERE th_mm_c_orderline_history_id
in (SELECT max(th_mm_c_orderline_history_id)
FROM th_mm_c_orderline_history
GROUP BY c_orderline_id)
) as docno
FROM c_order ord
INNER JOIN c_orderline on c_orderline.c_order_id = ord.c_order_id
INNER JOIN th_mm_c_orderline_history on th_mm_c_orderline_history.c_order_id=ord.c_order_id
You can use "order by statement" end of the whole select statement. Because of not use the column C_ORDERLINE_ID in select statement, it can be error in order by statement. Try this version in below.
SELECT DISTINCT
C_ORDER.DATEORDER,
(SELECT DOCNO
FROM TH_MM_C_ORDERLINE_HISTORY
WHERE C_ORDER_ID = C_ORDER_ID
AND TH_MM_C_ORDERLINE_HISTORY_ID IN ( SELECT MAX (TH_MM_C_ORDERLINE_HISTORY_ID)
FROM TH_MM_C_ORDERLINE_HISTORY
GROUP BY C_ORDERLINE_ID)) AS DOCNO,
C_ORDER.DOCUMENTNO
FROM C_ORDER
INNER JOIN C_ORDERLINE ON C_ORDERLINE.C_ORDER_ID = C_ORDER_ID
ORDER BY DOCNO, C_ORDERLINE_ID;

How to fix "ABAP INNER JOIN"

i'm trying to get a inner join from two select sentences but it doesn't work, what i am doing wrong?
i cant work with internal tables because inner join doesn't permit it.
clear: it_spfli.
refresh: it_spfli.
select
spfli-cityto
spfli-cityfrom
into TABLE it_spfli from(select spfli-cityto COUNT( * )from spfli group by spfli-cityto) as t1
INNER JOIN(select spfli-cityfrom COUNT( * )from spfli group by spfli-cityfrom) as t2
ON t1-cityto = t2-cityfrom.
i expect a table of more frequency city to and city from order by city to with table spfli.
First of all i don't think you are doing the right SELECT to get what you want.
I answer this question from the technical perspective. You can use WITH.
WITH +spf1 AS (
SELECT spfli~cityto AS cityto, COUNT(*) AS count FROM spfli GROUP BY spfli~cityto ) ,
+spf2 AS (
SELECT spfli~cityfrom AS cityfrom , COUNT(*) AS count FROM spfli GROUP BY spfli~cityfrom ) ,
+spf3 AS (
SELECT s1~cityto, s2~cityfrom FROM +spf1 AS s1 INNER JOIN +spf2 AS s2
ON s1~cityto = s2~cityfrom )
SELECT * FROM +spf3 INTO TABLE #DATA(lt_result).

TSQL Subquery in from

I am attempting to do a subquery which should work but I am missing something in the syntex.
I am trying:
select *
from (select * from (select *, row_number() over (partition by number,system order by number,system) as rc from [dbo].[info]) tk0 where tk0.rc =1) tkt
inner join [dbo].[QUEUES] pq
on pq.[QUEUE_NAME] = tkt.[QueueName] inner join [dbo].PLATFORMS] pl
on pl.id = pq.platform_id
and I get incorrect syntax near inner.
This works:
select *, row_number() over (partition by number,system order by number,system) as rc from [dbo].[info]) tk0 where tk0.rc =1
just missing a [ in platforms line .The below should work:
select *
from
(
select *
from
(
select
*, row_number() over (partition by number,system order by number,system) as rc
from [dbo].[info]
) tk0
where tk0.rc =1
) tkt
inner join [dbo].[QUEUES] pq
on pq.[QUEUE_NAME] = tkt.[QueueName]
inner join [dbo].[PLATFORMS] pl --correction done here
on pl.id = pq.platform_id
also you can write your where clause in join too:
select *
from
(
select
*, row_number() over (partition by number,system order by number,system) as rc
from [dbo].[info]
) tkt
inner join [dbo].[QUEUES] pq
on pq.[QUEUE_NAME] = tkt.[QueueName] and tkt.rc =1
inner join [dbo].[PLATFORMS] pl
on pl.id = pq.platform_id

Cannot call methods on char

This error seems to be coming from the following block of code. what is the possible cause of this error?
Cannot call method on char
INSERT INTO #ActiveTerminals
SELECT DISTINCT a.TerminalId, SerialNumber, a.[LoadTime] [LastSale]
FROM Terminal INNER JOIN
(
SELECT DISTINCT Ticket.TerminalId,max(LoadTime) [LoadTime] FROM
Ticket with (NOLOCK)
JOIN ProductDenomination with (NOLOCK) ON (ProductDenomination.DenominationId = Ticket.DenominationId)
WHERE ProductDenomination.ProductId NOT IN (SELECT * FROM dbo.fn_MVParam(#sExcludedProducts)) AND
datediff(day,LoadTime,#dteActiveSalesEndDate) <= #iLastSoldWithinDays
GROUP BY TerminalId
UNION ALL
SELECT DISTINCT VarTicket.TerminalId, max(TransactionDate) [LoadTime] FROM
VarTicket with (NOLOCK)
WHERE VarTicket.ProductId NOT IN (SELECT * FROM dbo.fn_MVParam(#sExcludedProducts)) AND
VarTicket.TerminalId NOT IN (SELECT TerminalId FROM #ActiveTerminals)
AND datediff(day,TransactionDate,#dteActiveSalesEndDate) <= #iLastSoldWithinDays
GROUP BY TerminalId
)a ON (Terminal.TerminalId = a.TerminalId.TerminalId)
ORDER BY a.TerminalId, SerialNumber
For this line:
)a ON (Terminal.TerminalId = a.TerminalId.TerminalId)
change it to this:
)a ON (Terminal.TerminalId = a.TerminalId)

Complex Full Outer Join

Sigh ... can anyone help? In the SQL query below, the results I get are incorrect. There are three (3) labor records in [LaborDetail]
Hours / Cost
2.75 / 50.88
2.00 / 74.00
1.25 / 34.69
There are two (2) material records in [WorkOrderInventory]
Material Cost
42.75
35.94
The issue is that the query incorrectly returns the following:
sFunction cntWO sumLaborHours sumLaborCost sumMaterialCost
ROBOT HARNESS 1 12 319.14 236.07
What am I doing wrong in the query that is causing the sums to be multiplied? The correct values are sumLaborHours = 6, sumLaborCost = 159.57, and sumMaterialCost = 78.69. Thank you for your help.
SELECT CASE WHEN COALESCE(work_orders.location, Work_Orders_Archived.location) IS NULL
THEN '' ELSE COALESCE(work_orders.location, Work_Orders_Archived.location) END AS sFunction,
(SELECT COUNT(*)
FROM work_orders
FULL OUTER JOIN Work_Orders_Archived
ON work_orders.order_number = Work_Orders_Archived.order_number
WHERE COALESCE(work_orders.order_number, Work_Orders_Archived.order_number) = '919630') AS cntWO,
SUM(Laborhours) AS sumLaborHours,
SUM(LaborCost) AS sumLaborCost,
SUM(MaterialCost*MaterialQuanity) AS sumMaterialCost
FROM work_orders
FULL OUTER JOIN Work_Orders_Archived
ON work_orders.order_number = Work_Orders_Archived.order_number
LEFT OUTER JOIN
(SELECT HoursWorked AS Laborhours, TotalDollars AS LaborCost, WorkOrderNo
FROM LaborDetail) AS LD
ON COALESCE(work_orders.order_number, Work_Orders_Archived.order_number) = LD.WorkOrderNo
LEFT OUTER JOIN
(SELECT UnitCost AS MaterialCost, Qty AS MaterialQuanity, OrderNumber
FROM WorkOrderInventory) AS WOI
ON COALESCE(work_orders.order_number, Work_Orders_Archived.order_number) = WOI.OrderNumber
WHERE COALESCE(work_orders.order_number, Work_Orders_Archived.order_number) = '919630'
GROUP BY CASE WHEN COALESCE(work_orders.location, Work_Orders_Archived.location) IS NULL
THEN '' ELSE COALESCE(work_orders.location, Work_Orders_Archived.location) END
ORDER BY sFunction
Try using the SUM function inside a derived table subquery when doing the full join to "WorkOrderInventory" like so...
select
...
sum(hrs) as sumlaborhrs,
sum(cost) as sumlaborcost,
-- calculate material cost in subquery
summaterialcost
from labordetail a
full outer join
(select ordernumber, sum(materialcost) as summaterialcost
from WorkOrderInventory
group by ordernumber
) b on a.workorderno = b.ordernumber
i created a simple sql fiddle to demonstrate this (i simplified your query for examples sake)
Looks to me that work_orders and work_orders_archived contains the same thing and you need both tables as if they were one table. So you could instead of joining create a UNION and use it as if it was one table:
select location as sfunction
from
(select location
from work_orders
union location
from work_orders_archived)
Then you use it to join the rest. What DBMS are you on? You could use WITH. But this does not exist on MYSQL.
with wo as
(select location as sfunction, order_number
from work_orders
union location, order_number
from work_orders_archived)
select sfunction,
count(*)
SUM(Laborhours) AS sumLaborHours,
SUM(LaborCost) AS sumLaborCost,
SUM(MaterialCost*MaterialQuanity) AS sumMaterialCost
from wo
LEFT OUTER JOIN
(SELECT HoursWorked AS Laborhours, TotalDollars AS LaborCost, WorkOrderNo
FROM LaborDetail) AS LD
ON COALESCE(work_orders.order_number, Work_Orders_Archived.order_number) = LD.WorkOrderNo
LEFT OUTER JOIN
(SELECT UnitCost AS MaterialCost, Qty AS MaterialQuanity, OrderNumber
FROM WorkOrderInventory) AS WOI
ON COALESCE(work_orders.order_number, Work_Orders_Archived.order_number) = WOI.OrderNumber
where wo.order_number = '919630'
group by sfunction
order by sfunction
The best guess is that the work orders appear more than once in one of the tables. Try these queries to check for duplicates in the two most obvious candidate tables:
select cnt, COUNT(*), MIN(order_number), MAX(order_number)
from (select order_number, COUNT(*) as cnt
from work_orders
group by order_number
) t
group by cnt
order by 1;
select cnt, COUNT(*), MIN(order_number), MAX(order_number)
from (select order_number, COUNT(*) as cnt
from work_orders_archived
group by order_number
) t
group by cnt
order by 1;
If either returns a row where cnt is not 1, then you have duplicates in the tables.