How to write multiset SELECT query in SQL Server - sql

Consider below tables:
T_WORK
-------------------
| Work_id | Cre_d |
-------------------
| 1 | 2016 |
| 2 | 2017 |
| 3 | 2018 |
-------------------
T_WORK_PARAM
-----------------------------------
| Work_id | Param_nm | Param_val |
-----------------------------------
| 1 | Name | John |
| 1 | Place | London |
| 1 | Date | 01-01-2018 |
| 2 | Name | Trump |
| 2 | Place | Newyork |
| 2 | Date | 02-02-2018 |
-----------------------------------
I need an output in below format
-----------------------------------
| | Name | John |
| 1 | Place | London |
| | Date | 01-01-2018 |
-----------------------------------
| | Name | Trump |
| 2 | Place | Newyork |
| | Date | 02-02-2018 |
-----------------------------------
In Oracle, I can achieve this with this query:
SELECT
T1.Work_id,
CAST (MULTISET (SELECT Param_nm, Param_val
FROM T_work_param T2
WHERE T2.Work_id = T1.Work_id) AS type_param_tbl)
FROM
T_work T1
Where type_param_tbl is table of (Param_nm varhar2(1000), PAram_val varhar2(1000));
How to write a similar query in SQL Server ?
If it is not possible in SQL Server - what is the best/usual way to return the desired output to the caller (web service)?

The way to achieve the result the way you want is actually by pivoting the Param_nm column. This will produce your result into a tabular format where you could parse/map it into your application.
Please, click here for see a SQLFiddle that shows what I'm talking about.
I hope this may help you!

Unfortunately you cannot do that in SQL server.
You may consider just joining the tables for somewhat similar result.

Related

Teradata SQL Assistant - How can I pivot or transpose large tables with many columns and many rows?

I am using Teradata SQL Assistant Version TD 16.10.06.01 ...
I have seen a lot people transpose data for set smallish tables but I am working on thousands of clients and need the break the columns up into Line Item Values to compare orders/highlight differences between orders. Problem is it is all horizontally linked and I need to transpose it to Id,Transaction id,Version and Line Item Value 1, Line Item Value 2... then another column comparing values to see if they changed.
example:
+----+------------+-----------+------------+----------------+--------+----------+----------+------+-------------+
| Id | First Name | Last Name | DOB | transaction id | Make | Location | Postcode | Year | Price |
+----+------------+-----------+------------+----------------+--------+----------+----------+------+-------------+
| 1 | John | Smith | 15/11/2001 | 1654654 | Audi | NSW | 2222 | 2019 | $ 10,000.00 |
| 2 | Mark | White | 11/02/2002 | 1661200 | BMW | WA | 8888 | 2016 | $ 8,999.00 |
| 3 | Bob | Grey | 10/05/2002 | 1667746 | Ford | QLD | 9999 | 2013 | $ 3,000.00 |
| 4 | Phil | Faux | 6/08/2002 | 1674292 | Holden | SA | 1111 | 2000 | $ 5,800.00 |
+----+------------+-----------+------------+----------------+--------+----------+----------+------+-------------+
hoping to change the data to :
+----+----------+----------+----------+----------------+----------+----------+----------------+---------+-----+
| id | trans_id | Vers_ord | Item Val | Ln_Itm_Dscrptn | Org_Val | Updt_Val | Amndd_Ord_chck | Lbl_Rnk | ... |
+----+----------+----------+----------+----------------+----------+----------+----------------+---------+-----+
| 1 | 1654654 | 2 | 11169 | Make | Audi BLK | Audi WHT | Yes | 1 | |
| 1 | 1654654 | 2 | 11189 | Location | NSW | WA | Yes | 2 | |
| 1 | 1654654 | 2 | 23689 | Postcode | 2222 | 6000 | Yes | 3 | |
+----+----------+----------+----------+----------------+----------+----------+----------------+---------+-----+
Recently with smaller data I created a table added in Values then used a case statement when value 1 then xyz with a product join ... and the data warehouse admins didn't mention anything out of order. but I only had row 16 by 200 column table to transpose ( Sum, Avg, Count, Median(function) x 4 subsets of clients) , which were significantly smaller than my current tables to make comparisons with.
I am worried my prior method will probably slow the data Warehouse down, plus take me significant amount of time to type the SQL.
Is there a better way to transpose large tables?

SQL Server 2016 count similar rows as a column without duplicating query

I have a SQL query that returns data similar to this pseudo-table:
| Name | Id1 | Id2 | Guid |
|------+-----+-----+------|
| Joe | 1 | 1 | 1123 |
| Joe | 2 | 1 | 1123 |
| Joe | 3 | 1 | 1120 |
| Jeff | 1 | 1 | 1123 |
| Moe | 3 | 42 | 1120 |
I would like to display an additional column on the output, listing the total number of records that have matching GUIDs to a given row, like this:
| Name | Id1 | Id2 | Guid | # Matching |
+------+-----+-----+------+------------+
| Joe | 1 | 1 | 1123 | 3 |
| Joe | 2 | 1 | 1123 | 3 |
| Joe | 3 | 1 | 1120 | 2 |
| Jeff | 1 | 1 | 1123 | 3 |
| Moe | 3 | 42 | 1120 | 2 |
I was able to accomplish this by joining the query with itself, and doing a count. However, the query is rather large and takes awhile to complete, is there any way I can accomplish this without joining the query with itself?
You want a window function:
select t.*, count(*) over (partition by guid) as num_matching
from t;

SQL - Multiple Selects with Case

+--------+---------+----------+----------+-------+------------+------------+
| F Name | L Name | Event ID | Group ID | Hours | Event Type | Event Name |
+--------+---------+----------+----------+-------+------------+------------+
| Bill | Johnson | 1 | | 3 | Event | Indirect |
| Janet | Jackson | | 1 | 1 | Group | |
| Bill | Johnson | | 1 | 1 | Group | |
| Chris | Margot | 2 | | 1.5 | Event | Direct |
| Janet | Jackson | | 1 | 1 | Group | |
+--------+---------+----------+----------+-------+------------+------------+
I have a table like this. I need to calculate the sum of the hours column if the event type is NOT group and direct.
I then need to sum hours if the event type is group but only once per person per group id. (So Janet would have 1 hour for her group not 2 because they have the same group ID. I am getting unexpected results.
I know It will involve a self join. The table is called public.event_by_wkr event_by_wkr in the FROM part of the query. I see this as rather difficult but it may not be. If you need more information I will provide it.

SQL Get cases related to a user and the number of files attached to that case

Hi everyone got a little stuck on an sql query. I have four tables
users
+----+------------+-----------+--------+
| id | first_name | last_name | active |
+----+------------+-----------+--------+
| 1 | Joe | Bloggs | 1 |
| 2 | John | Doe | 1 |
| 3 | Dave | Smith | 1 |
+----+------------+-----------+--------+
cases
+----+-----------+-------------+
| id | case_code | case_name |
+----+-----------+-------------+
| 1 | THEC12C | Test Case 1 |
| 2 | ABCD23A | Test Case 2 |
+----+-----------+-------------+
case_creditors
+----+---------+-------------+
| id | case_id | creditor_id |
+----+---------+-------------+
| 1 | 1 | 3 |
| 2 | 2 | 1 |
+----+---------+-------------+
case_files
+----+---------+----------+-----------+
| id | case_id | filename | file type |
+----+---------+----------+-----------+
| 1 | 1 | test.pdf | pfd |
| 2 | 2 | file.txt | txt |
| 3 | 2 | word.doc | doc |
+----+---------+----------+-----------+
When a user logs in i need to show a table with the users accociated cases the number of files attached to that case so if Joe Blogs loged in head see the following table
+-----------+-------------+-------+
| Case Code | Case Name | Files |
+-----------+-------------+-------+
| ABCD23A | Test Case 2 | 2 |
+-----------+-------------+-------+
ive been trying to write the sql statement to do this but am getting stuck on the query and wandered if someone could help give me some pointers. the sql ive gor so far
SELECT * FROM cases
(SELECT COUNT(*) FROM case_files WHERE case_files.case_id = cases.id) as Files
JOIN case_creditors ON cases.id = case_creditors.case_id
WHERE case_creditors.creditor_id = 1
managed to sort this with
SELECT
ips_case.*,
COUNT(case_files.file_id) AS Files
FROM
ips_case
LEFT JOIN case_files ON ips_case.id = case_files.case_id
JOIN case_creditors ON ips_case.id = case_creditors.case_id
WHERE
case_creditors.creditors_id = 4
GROUP BY
ips_case.id

Row to string value in Pervasive View

I have a table as follows
+----------------+----------+--------+
| purchase_order | text_seq | text |
+----------------+----------+--------+
| 1001 | 1 | screw |
| 1001 | 2 | m5x10 |
| 1001 | 3 | socket |
| 1002 | 1 | washer |
| 1002 | 2 | m5x10 |
+----------------+----------+--------+
From view need to get data as follows
+----------------+-------------------------+
| Purchase_order | text |
+----------------+-------------------------+
| 1001 | screw,m5x10,socket head |
| 1002 | washer,m5 |
+----------------+-------------------------+
There's not an easy way to do what you want. If you are using a recent version of PSQL, you can create a stored procedure or function to create the "text" field in the order you want (based on text_seq I would guess) and then use that result in the overall results.
My personal preference would be to retrieve the results from the database and then format them to my needs.