Looking for an efficient snowflake SQL query for my problem - sql

Table1:
ID|Days between installments |Number_of_Payments|First_payment_date|Last_payment_date**
001| 7 |5 | 2022-01-01 | 2022-01-29
002| 7 |2 | 2022-10-01 | 2022-10-08
003| 5 |3 | 2022-05-01 | 2022-05-15
004| 3 |1 | 2022-11-01 | 2022-11-01
Table2:
ID |Payment_date|Payment_amount
001|2022-01-01 |100
001|2022-08-01 |50
001|2022-15-01 |20
001|2022-22-01 |50
001|2022-29-01 |20
002|2022-10-01 |500
002|2022-10-08 |400
003|2022-05-01 |350
003|2022-05-10 |250
003|2022-05-15 |200
004|2022-11-01 |900
My final table should look like:
ID|First_payment_date|First_Installment_date|First_Payment_date|First_Payment_Amount|Second_Installment_date|Second_Payment_date|Second_Payment_Amount|Third_Installment_date|third_Payment_date|Third_Payment_Amount|Fourth_Installment_date|Fourth_Payment_date|Fourth_Payment_Amount|Fifth_Installment_date|Fifth_Payment_date|Fifth_Payment_Amount|Last_payment_date**
001|2022-01-01|2022-01-01|100|2022-08-01|2022-08-01|50|2022-15-01|2022-15-01|20|2022-22-01|2022-22-01|50|2022-29-01|2022-29-01|20|2022-29-01
002|2022-10-01|2022-10-01|500|2022-10-08|2022-10-08|400|NULL|NULL|NULL|NULL|NULL|NULL|NULL|NULL|NULL|2022-10-08
003|2022-05-01|2022-05-01|350|2022-05-10|2022-05-10|250|2022-05-15|2022-05-15|200|NULL|NULL|NULL|NULL|NULL|NULL|2022-05-15
004|2022-11-01|2022-11-01|900||NULL|NULL|NULL|NULL|NULL|NULL|NULL|NULL|NULL|NULL|NULL|NULL|2022-11-01
Could someone please let me know what is the best way to write this query. Thank you!

efficient
this means you have a method, so show it.
Also while we are anywhere near efficient, there is only efficiency inside a context, show/describe that.
While there are many great SQL coders on this site, reading the mind of people the cannot even be bother describing ANYTHING about their problem, is boring.

Related

Is it possible to edit Sphinx needtable contents?

For example, if I had this table:
.. needtable:: names of people
:style: datatables
:types: english
:columns: names, age, birth
and it looks like this:
|Name |Age |Birth |
-------------------------
|John man |20 |England |
|Jen Smith |30 |America |
Is it possible to manipulate the data so that only first names are shown?
|Name |Age |Birth |
-------------------------
|John |20 |England |
|Jen |30 |America |
Thought about using regex or :filter-func: but it doesn't work.

Noob needs advise on three tables in postgresql DB

I've very minor experience at working with databases( I only know the absolute basics). With that stated I guess my problem is rather easy to solve for more experienced minds.
My question is:
I need a way to be able to search for example "all types of Aluminium and all its sub_materials"?
I can do simple queries like
SELECT *
FROM sub_materials
WHERE category_id = 2;
So what I'm asking for is basically to be able to see the whole branch of Aluminium. I've looked at ltreeand Closure Tables But I'm to much of a Noob to figure it out by my self.
I believe I have to connect the tables somehow as "grandparent, parent, child" or something similar, but I've no idea if there is some other way or?
I'm not even sure if I'm doing this the right way.
Can someone advise me on this?
I've three tables in a database.(below are samples from the tables)
materials_category Holds all the categories for every material in the DB.
materials Holds the Category name and id, material_names and ids and the values for each material.
Some materials has sub_categories. not all but some.
3. sub_materials Holds the category info, material name and id, the sub_material name and id and the sub_material values.
1. `materials_category`
|category_id| category_name|
------------------------------
| 1 | Aggregate |
| 2 | Aluminium |
| 3 | Asphalt |
2. `materials`
|category_id |category_name |material_id |material_name|EE_1|EE_2|EC_1|EC_2
---------------------------------------------------------------------------
| 1 |Aggregate | 1 | General |3 |0 | 52 | 8
| 2 |Aluminium | 2 | General |55 |7 | 9 | 24
| 2 |Aluminium | 3 | Cast Pr |34 |30 | 22 | 28
| 2 |Aluminium | 4 | Extrud. |65 |16 | 8 | 74
| 2 |Aluminium | 5 | Rolled |15 | 0 | 9 | 61
| 3 |Asphalt | 6 |Asphalt, 4% |2 |22 | 6 | 54
| 3 |Asphalt | 7 |Asphalt, 5% |3 |91 | 1 | 4
3. `sub_materials`
|category_id|category_name|material_id|material_name|sub_mar_id|sub_mar_name|EE_1|EE_2|EC_1|EC_2|
|2 |Aluminium |2 |General |1 |Virgin |21 |5 |9 |60 |
|2 |Aluminium |2 |General |2 |Recycled |29 |3 |8 |9 |
Your tables are denormalised. This is usually not a good thing, unless this is a reporting only database.
Anyway, here's a start for what you're after. why don't you run it and give some feedback on whether it's what you want or not.
select *
from materials_category c
left outer join materials m
on c.category_id = m.category_id
left outer join sub_materials s
on s.material_id = m.material_id
where c.category_name = 'Aluminium'
Looking at your data, I'm guessing that 'recycled' could apply to any number of material categories, not just Aluminium? Would you have a whole bunch of 'Recycled' records in your sub_materials to allow for each material_category?

I want merge the entire row after that next row display the result

The actual output is:
|ctrcode|ctrname|empcode|empname|ewt |percent%|
|_______|_______|_______|_______|____|________|
|1 |Chain |1001 |A |25.6|15 |
|_______|_______|_______|_______|____|________|
|2 |Chain |1002 |B |15.6|10 |
|_______|_______|_______|_______|____|________|
but I want:
|empcode|empname|ewt |percent%|
|_______|_______|____|________|
|Chain |
|_____________________________|
|1001 |A |25.6|15 |
|_______|_______|____|________|
|1002 |B |15.6|10 |
|_______|_______|____|________|
How do I get it to look like this? I have used a DataGridView and filled the grid.
DataGridView is not able to merge cells, as far as I know. Please see this thread, to find an alternative solution: https://social.msdn.microsoft.com/Forums/windows/en-US/fea3dcff-5447-450a-8f7c-bb1c4f63371d/merging-cells-in-datagridview?forum=winformsdatacontrols
Have a nice weekend.

How to Merge 2 Rows into one by comma separate?

I need to merge this individual rows to one column, I now how to merge column by comma separated,
+---------------+-------+-------+
|CID |Flag |Value |
+---------------+-------+-------+
|1 |F |10 |
|1 |N |20 |
|2 |F |12 |
|2 |N |23 |
|2 |F |14 |
|3 |N |21 |
|3 |N |22 |
+---------------+-------+-------+
Desired Result can be anything,
+-----------+----------------------------+ +--------------------------+
|Part Number| Value | | Value |
+-----------+----------------------------+ +--------------------------+
| 1 | 1|F|10 ; 1|N|20 | Or | 1|F|10 ; 1|N|20 |
| 2 | 2|F|12 ; 2|N|23 ; 2|F|14 | | 2|F|12 ; 2|N|23 ; 2|F|14 |
| 3 | 3|N|21 ; 3|N|22 | | 3|N|21 ; 3|N|22 |
+-----------+----------------------------+ +--------------------------+
Note:
Any hint in right direction with small example is more than enough
EDIT :
I have massive data in tables like thousands of records where parent's and child relationship is present. I have to dump this into text files by comma separated values In single line as record. Think as primary record has relationship with so many other table then all this record has to be printed as a big line.
And I am trying to achieve by creating query so load can be distributed on database and only thing i have to worry about in business is just dumping logic into text files or whatever form we need in future.
You can try to use LISTAGG and your query will look like this:
select a.cid, a.cid || listagg(a.flag || '|' || a.value, ',')
from foo.dat a
group by a.cid
You can use different separators and of course play with how the result will be formatted.

SQL: How to get all descendants from a table with "many-to-many" related columns

I am still exploring SQL, hence I have an apparently easy question.
I have the following table in SQL Server 2008 R2.
As you see, this is a mapping table where there is a "many-to-many" relation between InstrumentIDs and ProductIDs:
|InstrumentID | ProductID |ID(PK)|
|-------------|-------------|------|
|10 |21 |0 |
|10 |22 |1 |
|11 |22 |2 |
|11 |23 |3 |
|12 |24 |4 |
|12 |25 |5 |
|----------------------------------|
I wish to write a query/SP which takes as an input let's say an InstrumentID and returns all the associated mappings extracted recursively.
For example, let's say that I provide InstrumentID = 10. Then, a satisfying result would be:
|InstrumentID | ProductID |ID(PK)|
|-------------|-------------|------|
|10 |21 |0 |
|10 |22 |1 |
|11 |22 |2 |
|11 |23 |3 |
|----------------------------------|
What is the best way of accomplishing this ?
An example would definitely be useful.
I have tried the following query using CTE:
WITH Map
AS (
-- Anchor
SELECT InstrumentID, ProductID
FROM InstrumentProduct
WHERE InstrumentID IN (10)
UNION ALL
-- Recursive
SELECT IP.InstrumentID, IP.ProductID
FROM InstrumentProduct IP
INNER JOIN Map
ON IP.InstrumentID = Map.InstrumentID
OR IP.ProductID = Map.ProductID
)
SELECT *
FROM Map
OPTION (MAXRECURSION 50);
But query is executed with an error: "The statement terminated. The maximum recursion 5 has been exhausted before statement completion."
However the results are returned apparently correct, but duplicated.
Any kind of help and advice is definitely helpful.
Thanks!