Include null values and joins properly in query - sql

I am using oracle sqldeveloper and I'm trying to generate results that include customer information under certain criteria that is searched by date range. I feel like I am close however I would like to include accounts that apply all the criteria but haven't made payments as well.
My intended result is to look something like this:
CYCLENUMB | WOCREATIONDATE | POSTINGDATE | CUSTOMERNUMBER | FIRSTNAME | LASTNAME | ADDRESS | WOORDERTYPE | DESCRIPTION | PAYMENT
12 | 29-JUL-20 | 01-AUG-20 | 345506 | Luke | Skywalker| 123 Lakeway Dr. | 636 |Completed | $100
24 | 01-AUG-20 | 07-AUG-20 | 456923 | Leia | Skywalker| 456 Lakeway Dr. | 636 |Completed | $300
35 | 17-AUG-20 | 24-AUG-20 | 596854 | Chewy | Wookie | 789 Lakeway Dr. | 636 |Completed | NULL
80 | 21-AUG-20 | 28-AUG-20 | 695067 | Han | Solo | 432 Wrongturn Dr.| 636 |Completed | NULL
66 | 25-AUG-20 | 30-AUG-20 | 235645 | Count | Dooku | 534 Wrongturn Dr.| 636 |Completed | $225
However my results are coming out just like this
CYCLENUMB | WOCREATIONDATE | POSTINGDATE | CUSTOMERNUMBER | FIRSTNAME | LASTNAME | ADDRESS | WOORDERTYPE | DESCRIPTION | PAYMENT
12 | 29-JUL-20 | 01-AUG-20 | 345506 | Luke | Skywalker| 123 Lakeway Dr. | 636 |Completed | $100
24 | 01-AUG-20 | 07-AUG-20 | 456923 | Leia | Skywalker| 456 Lakeway Dr. | 636 |Completed | $300
66 | 25-AUG-20 | 30-AUG-20 | 235645 | Count | Dooku | 534 Wrongturn Dr.| 636 |Completed | $225
Below is the query I'm trying to run
select customermaster.cyclenumber as CYCLENUMB,
workorder.creationdate as WOCREATIONDATE,
MAX(cushistory.postingdate) as POSTINGDATE,
cushistory.customernumber as CUSTOMERNUMBER,
customerpersonalinfo.firstname as FIRSTNAME,
customerpersonalinfo.lastname as LASTNAME,
premiseaddress.Concatenated_Address as ADDRESS,
workorder.ordertype as WOORDERTYPE,
workorderstatus.description as DESCRIPTION,
SUM(cushistory.moneysegment1) as PAYMENT
from customermaster, workorder, customerpersonalinfo,
(select
premiseaddress.company as COMPANY,
premiseaddress.premisenumber as PREMISENUMBER,
((to_char(premiseaddress.currpremisestreetnumber) || ' ') || premiseaddress.currpremisestreetname) as Concatenated_Address
from premiseaddress)
premiseaddress, workorderstatus, cushistory
where workorder.ordertype = 636
and cushistory.moneytypecode1 = 7
and workorder.application = 3
and cushistory.postingdate between '01-Aug-20' and '31-Aug-20'
and customermaster.customernumber = cushistory.customernumber
and cushistory.customernumber = workorder.customernumber
and customermaster.company = workorder.company
and customermaster.accounttype = workorder.application
and customermaster.customernumber = workorder.customernumber
and workorder.application = workorderstatus.application
and workorder.completecode = workorderstatus.workorderstatus
and customermaster.company = customerpersonalinfo.company
and customermaster.occupantcisnumber =customerpersonalinfo.cisnumber
and customermaster.company = premiseaddress.company
and customermaster.premisenumber = premiseaddress.premisenumber
GROUP BY customermaster.cyclenumber,
workorder.wocreationdate ,
cushistory.postingdate,
customermaster.customernumber,
customerpersonalinfo.firstname,
customerpersonalinfo.lastname,
premiseaddress.Concatenated_Address,
workorder.ordertype,
workorderstatus.description
ORDER BY workorder.creationdate asc
I included a subquery for simplifying customer address. Postingdate from cushistory is the date range filer I am applying.
Please note that custhistory table is the main table that holds customernumbers and payments. I wanted to left join it with workorder table to include null values but haven't figured out a surefire way to do it.

Related

Cumulative SUM in a query (SQL access)

Using MS access SQL I have a query (actually a UNION made of multiple queries) and need a cumulative sum (actually a statement of account which items are in chronological order).
How do I get a cumulative sum?
Since they are duplicates by date I have to add a new ID, however, SQL in MS access does not seem to have ROW_ID or similar.
So, we need to sort donation data into chronological order across multiple tables with duplicates. First combine all the tables of donators in one query which sets up the simplest syntax. Then to put things in order we need to have an order for the duplicate dates. The dataset has two natural ways to sort duplicate dates including the donator and the amount. For instance, we could decide that after the date bigger donations come first, If the rule is complicated enough we abstract it to a code module and into public function and include it in the query so that we can sort by it:
'Sorted Donations:'
SELECT (BestDonator(q.donator)) as BestDonator, *
FROM tblCountries as q
UNION SELECT (BestDonator(j.donator)) as BestDonator, *
FROM tblIndividuals as j
ORDER BY EvDate Asc, Amount DESC , BestDonator DESC;
Public Function BestDonator(donator As String) As Long
BestDonator = Len(donator) 'longer names are better :)'
End Function
with sorted donations we have settled on an order for the duplicate dates and have combined both individual donations and country donations, so now we can calculate the running sum directly using either dsum or a subquery. There is no need to calculate row id. The tricky part is getting the syntax correct. I ended up abstracting the running sum calculation to a function and omitting BestDonator because I couldn't easily paste together this query in the query designer and I ran out of time to bug fix
Public Function RunningSum(EvDate As Date, Amount As Currency)
RunningSum = DSum("Amount", "Sorted Donations", "(EvDate < #" & [EvDate] & "#) OR (EvDate = #" & [EvDate] & "# AND Amount >= " & [Amount] & ")")
End Function
Carefully note the OR in the Dsum part of the RunningSum calculation. This is the tricky part to summing the right amounts.
'output
-------------------------------------------------------------------------------------
| donator | EvDate | Amount | RunningSum |
-------------------------------------------------------------------------------------
| Reiny | 1/10/2020 | 321 | 321 |
-------------------------------------------------------------------------------------
| Czechia | 3/1/2020 | 7455 | 7776 |
-------------------------------------------------------------------------------------
| Germany | 3/18/2020 | 4222 | 11998 |
-------------------------------------------------------------------------------------
| Jim | 3/18/2020 | 222 | 12220 |
-------------------------------------------------------------------------------------
| Australien | 4/15/2020 | 13423 | 25643 |
-------------------------------------------------------------------------------------
| Mike | 5/31/2020 | 345 | 25988 |
-------------------------------------------------------------------------------------
| Portugal | 6/6/2020 | 8755 | 34743 |
-------------------------------------------------------------------------------------
| Slovakia | 8/31/2020 | 3455 | 38198 |
-------------------------------------------------------------------------------------
| Steve | 9/6/2020 | 875 | 39073 |
-------------------------------------------------------------------------------------
| Japan | 10/10/2020 | 5234 | 44307 |
-------------------------------------------------------------------------------------
| John | 10/11/2020 | 465 | 44772 |
-------------------------------------------------------------------------------------
| Slowenia | 11/11/2020 | 4665 | 49437 |
-------------------------------------------------------------------------------------
| Spain | 11/22/2020 | 7677 | 57114 |
-------------------------------------------------------------------------------------
| Austria | 11/22/2020 | 3221 | 60335 |
-------------------------------------------------------------------------------------
| Bill | 11/22/2020 | 767 | 61102 |
-------------------------------------------------------------------------------------
| Bert | 12/1/2020 | 755 | 61857 |
-------------------------------------------------------------------------------------
| Hungaria | 12/24/2020 | 9996 | 71853 |
-------------------------------------------------------------------------------------

SQL Multiple Joining

I'm trying to join the two table and at the same time getting the value of the certain column by using inner join, I tried joining until the 3rd diagram but when it comes to the fourth it doesn't display the null values, how can I display the values of the 4th column even the null values
here's the code of the SQL
betl.user_id,
betl.agent_id,
ah1.parent_id,
ah2.user_id,
ah3.user_id AS parent_of_agent
FROM
wpc16_02.bets_logs betl
INNER JOIN
wpc16_02.agent_heirarchy ah1 ON betl.agent_id = ah1.user_id
INNER JOIN
wpc16_02.agent_heirarchy ah2 ON ah1.parent_id = ah2.id
INNER JOIN
wpc16_02.agent_heirarchy ah3 ON ah2.parent_id = ah3.id
WHERE
fight_id = 1930 AND agent_income = 0
here's what I'm trying to achieve by using innerjoins:
Here's the result I got when trying the joining upto the 3rd diagram:
user_id | agent_id | parent_id | user_id_of_parent
15012 | 2212 | 96 | 160
227097 | 22061 | 266 | 64
465174 | 464899 | 126 | 211
505094 | 504767 | 980 | 5358
241158 | 8281 | 18 | 67
463344 | 462715 | 751 | 3420
184396 | 29870 | 502 | 2123
486847 | 43225 | 164 | 234
482120 | 482023 | 4430 | 46469
369628 | 217212 | 8283 | 109697
When joining upto 4th diagram:
user_id | agent_id | parent_id | user_id_of_parent | master_uid
184396 | 29870 | 502 | 2123 | 160
482120 | 482023 | 4430 | 46469 | 699
369628 | 217212 | 8283 | 109697 | 71
97287 | 93996 | 7332 | 93866 | 3114
113287 | 113228 | 2714 | 20652 | 4050
366287 | 361918 | 17603 | 235880 | 234
439935 | 236147 | 3776 | 40054 | 103
480201 | 436936 | 1041 | 5761 | 160
456400 | 456248 | 32901 | 431900 | 240
502877 | 497592 | 2571 | 20845 | 3918
notice the other datas have been removed because when I joined the 4th diagram some of the results are null
You seem to want LEFT JOIN. It is a little unclear what the exact query is, because your question doesn't have information such as which columns are in which tables.
But the idea is:
SELECT . . .
FROM wpc16_02.bets_logs betl LEFT JOIN
wpc16_02.agent_heirarchy ah1
ON betl.agent_id = ah1.user_id LEFT JOIN
wpc16_02.agent_heirarchy ah2
ON ah1.parent_id = ah2.id LEFT JOIN
wpc16_02.agent_heirarchy ah3
ON ah2.parent_id = ah3.id
WHERE betl.fight_id = 1930 AND betl.agent_income = 0
This assums that flight_id and agent_income are from the first table. If they are in one of the hierarchy tables, then the conditions should go in the appropriate ON clause.

How can I find next higher number based on certain where-conditions?

I have to find the next higher sequence-number depending on certain where-conditions:
TABLE:
+-------+------------------+---------------------------+
| Seq | Start_Time | Queue |
+-------+------------------+---------------------------+
| 34962 | 28.07.2020 17:06 | PQ_NEW PRICE REQUEST GMDM |
| 35393 | 29.07.2020 11:03 | |
| 35394 | 29.07.2020 11:03 | |
| 42886 | 04.09.2020 14:16 | PQ_NEW PRICE REQUEST GMDM |
| 42887 | 04.09.2020 14:16 | PQ_NEW PRICE REQUEST GMDM |
| 42888 | 04.09.2020 14:16 | |
| 42889 | 04.09.2020 14:16 | |
| 42890 | 04.09.2020 14:17 | PQ_COST SWEDEN |
| 42891 | 04.09.2020 14:17 | PQ_COST SWEDEN |
| 42892 | 04.09.2020 14:17 | |
| 42893 | 04.09.2020 14:17 | |
| 42894 | 04.09.2020 14:17 | PQ_NEW PRICE REQUEST GMDM |
| 42895 | 04.09.2020 14:17 | PQ_NEW PRICE REQUEST GMDM |
+-------+------------------+---------------------------+
Example select:
SELECT
start_time
FROM table
WHERE
queue <> 'PQ_NEW PRICE REQUEST GMDM'
AND seq **IS NEXT HIGHER SEQ-VALUE COMPARED TO** (SELECT seq
FROM table
WHERE
queue = 'PQ_NEW PRICE REQUEST GMDM'
AND seq = MIN(seq))
Expected result from table for NEXT HIGHER SEQ-VALUE COMPARED TO:
42890
This would be the next higher number where the condition is met, based on the minimum-sequence number and the condition in the sub-select (34962).
How can I find exactly the next higher sequence-number under certain where-conditions?
Is there even an Oracle-SQL-command? By the way: order by is not an option for the scenario I need it.
SELECT *,
(
select min(seq) from table t2
where t2.seq > t.seq and queue = 'PQ_NEW PRICE REQUEST GMDM'
) as next_seq
FROM table t
WHERE queue <> 'PQ_NEW PRICE REQUEST GMDM';
Try ranking function after calculating the time differences.

How can I summarize / pivot data with oracle sql

I have a table containing geological resource information.
| Property | Zone | Area | Category | Tonnage | Au_gt | Au_oz |
|----------|------|-------------|-----------|---------|-------|-------|
| Ket | Eel | Open Pit | Measured | 43400 | 5.52 | 7700 |
| Ket | Eel | Open Pit | Inferred | 51400 | 5.88 | 9700 |
| Ket | Eel | Open Pit | Indicated | 357300 | 6.41 | 73600 |
| Ket | Eel | Underground | Measured | 3300 | 7.16 | 800 |
| Ket | Eel | Underground | Inferred | 14700 | 6.16 | 2900 |
| Ket | Eel | Underground | Indicated | 168100 | 8.85 | 47800 |
I would like to summarize the data so that it can be read more easily by our clients.
| Property | Zone | Category | Open_Pit_Tonnage | Open_Pit_Au_gt | Open_Pit_Au_oz | Underground_tonnage | Underground_au_gt | Underground_au_oz | Combined_tonnage | Combined_au_gt | Combined_au_oz |
|----------|------|-----------|------------------|----------------|----------------|---------------------|-------------------|-------------------|------------------|----------------|----------------|
| Ket | Eel | Measured | 43,400 | 5.52 | 7,700 | 3,300 | 7.16 | 800 | 46,700 | 5.64 | 8,500 |
| Ket | Eel | Indicated | 357,300 | 6.41 | 73,600 | 168,100 | 8.85 | 47,800 | 525,400 | 7.19 | 121,400 |
| Ket | Eel | Inferred | 51,400 | 5.88 | 9,700 | 14,700 | 6.16 | 2,900 | 66,100 | 5.94 | 12,600 |
I'm fairly new to pivot tables. How could I write a query to translate and summarize the data?
Thanks!
If your Oracle version is 11.1 or higher (which it should be if you are a relatively new user!) then you can use the PIVOT operator, as shown below.
Note that the result of the PIVOT operation can be given an alias (I used p) - this makes it easier to write the SELECT clause.
I assumed the name of your table is geological_data - replace it with your actual table name.
select p.*
, open_pit_tonnage + underground_tonnage as combined_tonnage
, open_pit_au_gt + underground_au_gt as combined_au_gt
, open_pit_au_oz + underground_au_oz as combined_au_oz
from geological_data
pivot (sum(tonnage) as tonnage, sum(au_gt) as au_gt, sum(au_oz) as au_oz
for area in ('Open Pit' as open_pit, 'Underground' as underground)) p
;
Conditional aggregation is a simple method:
select Property, Zone, Category,
max(case when area = 'Open Pit' then tonnage end) as open_pit_tonnage,
max(case when area = 'Open Pit' then Au_gt end) as open_pit_Au_gt,
max(case when area = 'Open Pit' then Au_oz end) as open_pit_Au_ox,
max(case when area = 'Underground' then tonnage end) as Underground_tonnage,
max(case when area = 'Underground' then Au_gt end) as Underground_Au_gt,
max(case when area = 'Underground' then Au_oz end) as Underground_Au_ox
from t
group by Property, Zone, Category
SQL Server PIVOT operator is used to convert rows to columns.
Goal is to turn the category names from the first column of the output into multiple columns and count the number of products for each category
This query reference can be taken into account for you above table:
SELECT * FROM
(
SELECT
category_name,
product_id,
model_year
FROM
production.products p
INNER JOIN production.categories c
ON c.category_id = p.category_id
) t
PIVOT(
COUNT(product_id)
FOR category_name IN (
[Children Bicycles],
[Comfort Bicycles],
[Cruisers Bicycles],
[Cyclocross Bicycles],
[Electric Bikes],
[Mountain Bikes],
[Road Bikes])
) AS pivot_table;

How to update column in table from two different tables USING DML Command

I have three different tables here:
df_umts_relation table:
|---------------------|------------------|---------------------|------------------|------------------|
| cell_name | n_cell_name | technology | source_ops_num | target_ops_num |
|---------------------|------------------|---------------------|------------------|------------------|
| 121 | 221 | UMTS | 1 | | |
|---------------------|------------------|---------------------|------------------|------------------|
| 122 | 222 | GSM | 2 | | |
|---------------------|------------------|---------------------|------------------|------------------|
| 123 | 223 | UMTS | 3 | | |
|---------------------|------------------|---------------------|------------------|------------------|
| 124 | 224 | GSM | 4 | | |
|---------------------|------------------|---------------------|------------------|------------------|
| 125 | 225 | GSM | 5 | | |
|---------------------|------------------|---------------------|------------------|------------------|
| 126 | 226 | UMTS | 6 | | |
|---------------------|------------------|---------------------|------------------|------------------|
| 127 | 227 | UMTS | 7 | | |
|---------------------|------------------|---------------------|------------------|------------------|
So now I want to update target_ops_num from the two below tables
df_umts_carrier table as this table contains those thow columns I want to work on them and contains some integer values also:
|---------------------|------------------|
| opsnum_umts | cell_name_umts |
|---------------------|------------------|
as I have another table called df_gsm_carrier:
|---------------------|------------------|
| opsnum_gsm | cellname |
|---------------------|------------------|
So All I need I want to update [MyNewDatabase].[dbo].[df_umts_relation].[target_ops_num] CASE WHEN technologyis UMTS then update from table df_umts_carrier ELSE technology is GSM then update from df_gsm_carrier on n_cell_name = cell_name_umts and on n_cell_name = cellname
So I tried to create a query as the below one works with one condition only and it's update the the rows which is UMTS only:
UPDATE [MyNewDatabase].[dbo].[df_umts_relation]
SET [MyNewDatabase].[dbo].[df_umts_relation].[target_ops_num] = [MyNewDatabase].[dbo].[df_umts_carrier].[opsnum_umts]
FROM [MyNewDatabase].[dbo].[df_umts_relation]
INNER JOIN [MyNewDatabase].[dbo].[df_umts_carrier]
ON [n_cell_name] = [cell_name_umts]
and works fine but doesn't update the rows which contains GSM...
On other way I tried to create a query to handle this but it didn't update the GSM part and take a long of time:
UPDATE [MyNewDatabase].[dbo].[df_umts_relation]
SET [MyNewDatabase].[dbo].[df_umts_relation].[target_ops_num] = (CASE WHEN [MyNewDatabase].[dbo].[df_umts_relation].[technology] = 'UMTS'
THEN [MyNewDatabase].[dbo].[df_umts_carrier].[opsnum_umts] ELSE [MyNewDatabase].[dbo].[df_gsm_carrier].[opsnum_gsm] END)
FROM [MyNewDatabase].[dbo].[df_umts_relation]
LEFT JOIN [MyNewDatabase].[dbo].[df_umts_carrier]
ON [n_cell_name] = [cell_name_umts]
LEFT JOIN [MyNewDatabase].[dbo].[df_gsm_carrier]
ON [n_cell_name] = [cell_name]
So any one have any idea how to solve this?
Please check if this will help.
update df_umts_relation
set target_ops_num = ( select case when dur.technology = 'UMTS' then du.cell_name_umts
when dur.technology = 'GSM' then dg.cellname
end
from df_umts_relation dur
left join df_umts_carrier du on dur.n_cell_name = du.opsnum_umts
left join df_gsm_carrier dg on dur.n_cell_name = dg.opsnum_umts
where dur.id= df_umts_relation.id)
Here is a demo