How to select SQL join table with not redundancy value - sql

I have two tables:
Table 1: Input
Namecode | Number |
01 50
01 49
02 10
03 40
04 100
Table 2: Output
Namecode | Number |
01 15
02 25
This is my SQL query:
SELECT *
FROM Input
LEFT JOIN Output ON Input.Namecode = Output.Namecode
This is the result:
Namecode | Number | Namecode | Number
01 50 01 15
01 49 01 15
02 10 02 25
03 40 NULL NULL
04 100 NULL NULL
I want the result to be like this:
Namecode | Number | Namecode | Number
01 50 01 15
01 49 NULL NULL
02 10 02 25
03 40 NULL NULL
04 100 NULL NULL
How can I get this output? I want the Namecode 01 only show 1 row, the row left have no value because in Output table Namecode 01 only have 1 row
What query do I need to get the result I want?

You seem want to match max(Namecode) value if there are duplicate Namecode
You can try this query, write a subquery and left join
SELECT t1.*,t3.*
from Input t1
LEFT JOIN (SELECT Namecode,MAX(Number) Number FROM Input GROUP BY Namecode ) t2
ON t1.Number = t2.Number
LEFT JOIN Output t3
on t2.Namecode = t3.Namecode1
sqlfiddle
Result
Namecode Number Namecode1 Number1
01 50 01 15
02 10 02 25
01 49 null null
03 40 null null
04 100 null null

Related

inner join when the key is two columns

I need to create a summary table Which is a summary of the targets and sales.
Here are the tables.
target_table
customer_id
month
target
101
05
60
101
06
60
102
05
80
102
05
85
selse_table
customer_id
month
selse
101
05
40
101
06
70
102
05
90
102
05
60
Here is my query
CREATE TABLE SUMMERY
AS SELECT SALSE.customrt_id, SALSE.month, SALSE.selse, targets.target
FROM SALSE
Inner join TARGETS
on SALSE.CUSTOMER_ID=TARGETS.customer_ID
I try to use INNER JOIN but the problem is that it is not enough for me just the customer_id column because the same customer has different destinations every month.
Is my query correct? How to do the INNER JOIN right?
Don't understand your question very well,like this?
on SALSE.CUSTOMER_ID=TARGETS.customer_ID and SALSE.[MONTH]=TARGETS.[MONTH]

Deleting values on Hana Table based on a field value

I am working on a hana table and i am trying to delete a table if it contains value from a list.
A B
22 01
22 01
22 02
22 06
23 01
23 01
23 06
I will like to drop some values from this table and have this.
A B
22 01
22 01
22 06
23 01
23 01
23 06
Basically i will like to most likely do a count and check if column B consists of 01 AND 02, if it does drop 02 and if it consists of only 01 leave as it is.
This seems virtually impossible with almost every sql script i have tried
SELECT BP, COUNT(*) AS SO FROM "EH"."BP_CUST" GROUP BY BP;
This scripts gets the count of each row and put it in SO column.
after that maybe do an if statement on the SO column and delete if the B field contains 01 and 02?
I tried doing and IF statement then select and i could not get it to work either.
A B
22 01
22 01
22 02
22 06
23 01
23 01
23 06
24 02
Becomes
A B
22 01
22 01
22 06
23 01
23 01
23 06
24 02
If I understand correctly, you want:
select c.*
from "EH"."BP_CUST" c
where c.b <> '02' or
not exists (select 1
from "EH"."BP_CUST" c2
where c2.a = c.a and c2.b = '01'
);
Your question says "delete". But I think the intention is to select "02" rows only when there is no "01" row for the same a (and all other rows).
If I understood correctly, this might be the solution:
DELETE BP_CUST
WHERE A IN
(
SELECT
BP_CUST.A
FROM
(
SELECT
A
, COUNT(CASE WHEN B != '02' THEN 1 ELSE NULL END) AS NOT_02
, COUNT(CASE WHEN B = '02' THEN 1 ELSE NULL END) AS IS_02
FROM BP_CUST
GROUP BY A
) AS t_delete
JOIN BP_CUST ON BP_CUST.A = t_delete.A
WHERE B = '02' AND NOT_02 > 0 AND IS_02 > 0
)
AND B = '02'

Adding rows, running count, running sum to query results

I have a table with the following ddl.
CREATE TABLE "LEDGER"
("FY" NUMBER,
"FP" VARCHAR2(20 BYTE),
"FUND" VARCHAR2(20 BYTE),
"TYPE" VARCHAR2(2 BYTE),
"AMT" NUMBER
)
The table contains the following data.
REM INSERTING into LEDGER
SET DEFINE OFF;
Insert into LEDGER (FY,FP,FUND,TYPE,AMT) values (15,'03','A','03',1);
Insert into LEDGER (FY,FP,FUND,TYPE,AMT) values (15,'04','A','03',2);
Insert into LEDGER (FY,FP,FUND,TYPE,AMT) values (16,'04','A','03',3);
Insert into LEDGER (FY,FP,FUND,TYPE,AMT) values (12,'05','A','04',6);
based on the partition of fy,fp,fund and type I would like to write a query to keep a running count from the beginning of fp(fp though it is a varchar it represents a number in the month. i.E 2 equals february and 3 equals march etc.) to a hard number of 14. So taking a closer look at the data you will notice that in FY 15 the max period is 04 so i must add another 10 periods to my report to get my report to have the full 14 periods. here is the expected output.
here is what i tried, but I'm just simply stumbling all together on this.
WITH fy_range AS
(
SELECT MIN (fy) AS min_fy
, MAX (fy) AS max_fy
FROM ledger
),all_fys AS
(
SELECT min_fy + LEVEL - 1 AS fy
FROM fy_range
CONNECT BY LEVEL <= max_fy + 1 - min_fy
)
,all_fps AS
(
SELECT TO_CHAR (LEVEL, 'FM00') AS fp
FROM dual
CONNECT BY LEVEL <= 14
)
SELECT
FUND
,G.TYPE
,G.FY
,G.FP
,LAST_VALUE(G.AMT ignore nulls) OVER (PARTITION BY G.FUND ORDER BY Y.FY P.FP ) AS AMT
FROM all_fys y
CROSS JOIN all_fps p
LEFT OUTER JOIN LEDGER G PARTITION BY(FUND)
ON g.fy = y.fy
AND g.fp = p.fp;
but I end up with a bunch of nulls and some strange results.
This may not be the most efficient solution, but it is easy to understand and maintain. First (in the most deeply nested subquery) we find the min FP for each combination of FY, FUND and TYPE. Then we use a CONNECT BY query to fill all the FP for all FY, FUND, TYPE combinations (up to the hard upper limit of 14). Then we left-outer-join to the original data in the LEDGER table. So far we densified the data. In the final query (the join) we also add the column for the cumulative sum - that part is easy after we densified the data.
TYPE is an Oracle keyword, so it is probably best not to use it as a column name. It is also best not to use double-quoted table and column names (I had to use upper case everywhere because of that). I also made sure to convert from varchar2 to number and back to varchar2 - we shouldn't rely on implicit conversions.
select S.FY, to_char(S.FP, 'FM09') as FP, S.FUND, S.TYPE,
sum(L.AMT) over (partition by S.FY, S.FUND, S.TYPE order by S.FP) as CUMULATIVE_AMT
from (
select FY, MIN_FP + level - 1 as FP, FUND, TYPE
from (
select FY, min(to_number(FP)) as MIN_FP, FUND, TYPE
from LEDGER
group by FY, FUND, TYPE
)
connect by level <= 15 - MIN_FP
and prior FY = FY
and prior FUND = FUND
and prior TYPE = TYPE
and prior sys_guid() is not null
) S left outer join LEDGER L
on S.FY = L.FY and S.FP = L.FP and S.FUND = L.FUND and S.TYPE = L.TYPE
;
Output:
FY FP FUND TYPE CUMULATIVE_AMT
--- --- ---- ---- --------------
12 05 A 04 6
12 06 A 04 6
12 07 A 04 6
12 08 A 04 6
12 09 A 04 6
12 10 A 04 6
12 11 A 04 6
12 12 A 04 6
12 13 A 04 6
12 14 A 04 6
15 03 A 03 1
15 04 A 03 3
15 05 A 03 3
15 06 A 03 3
15 07 A 03 3
15 08 A 03 3
15 09 A 03 3
15 10 A 03 3
15 11 A 03 3
15 12 A 03 3
15 13 A 03 3
15 14 A 03 3
16 04 A 03 3
16 05 A 03 3
16 06 A 03 3
16 07 A 03 3
16 08 A 03 3
16 09 A 03 3
16 10 A 03 3
16 11 A 03 3
16 12 A 03 3
16 13 A 03 3
16 14 A 03 3

How do I add specific values from one different table to columns in a row based off of values in another table?

In SQL Server I have 2 tables that looks like this:
TEST SCRIPT 'a collection of test scripts'
(PK)
ID Description Count
------------------------
A12 Proj/Num/Dev 12
B34 Gone/Tri/Tel 43
C56 Geff/Ben/Dan 03
SCRIPT HISTORY 'the history of the aforementioned scripts'
(FK) (PK)
ScriptID ID Machine Date Time Passes
----------------------------------
A12 01 DEV012 6/26/15 16:54 4
A12 02 DEV596 6/28/15 13:12 9
A12 03 COM199 3/12/14 14:22 10
B34 04 COM199 6/30/13 15:45 12
B34 05 DEV012 6/30/15 13:13 14
B34 06 DEV444 6/12/15 11:14 14
C56 07 COM321 6/29/14 02:19 12
C56 08 ANS042 6/24/14 20:10 18
C56 09 COM432 6/30/15 12:24 4
C56 10 DEV444 4/20/12 23:55 2
In a single query, how would I write a select statement that takes just one entry for each DISTINCT script in TEST SCRIPT and pairs it with the values in only the TOP 1 most recent run time in SCRIPT HISTORY?
For example, the solution to the example tables above would be:
OUTPUT
ScriptID ID Machine Date Time Passes
---------------------------------------------------
A12 02 DEV596 6/28/15 13:12 9
B34 05 DEV012 6/30/15 13:13 14
C56 09 COM432 6/30/15 12:24 4
The way you describe the problem is almost directly as cross apply:
select h.*
from testscript ts cross apply
(select top 1 h.*
from history h
where h.scriptid = ts.id
order by h.date desc, h.time desc
) h;
Please try something like this:
select *
from SCRIPT SCR
left join (select MAX(SCRIPT_HISTORY.Date) as Date, SCRIPT_HISTORY.ScriptID
from SCRIPT_HISTORY
group by SCRIPT_HISTORY.ScriptID
) SH on SCR.ID = SH.ScriptID

SQLite: Group records with nearest integer field

There is a table with integer field. I need to write a query which returns groups with the following condition: min value of the field in the some group differs more than N to max value in the next group.
Example with N=10.
SQL query for the table
01 A A 1
02 A B 9
03 B B 11
04 B C 22
05 C C 29
should return
01 A A 1 0
02 A B 9 0
03 B B 11 0
04 B C 22 1
05 C C 29 1
Here is a similar question for Python. How to do this in SQLite?