SQL - Combine multiple columns into one column with more rows - sql

I have a table with 20 columns that all display the same thing. I'm not sure why my company set it up like this, but I cannot make changes to the table.
With that in mind, here is what I need to do. I need to populate a drop down list with insurance company names. Therefore I need to find unique values across the entire table.
Using a Group By clause is out of the question because I need unique values across the entire table. No single column contains all the possible values. My only thought was to combine all the columns of the table together. I've seen this done using two pipes ( || ). But that concatenates the columns which does not help me.
I need to join two (or twenty) columns together and add their rows together. I.e. if I started out with 20 columns and 100 rows, I need to have one column with 2000 rows. This way I can select unique values using the Group By clause.
Any help would be greatly appreciated!
Sample of what I'm trying to accomplish:
Sample original table:
--Ins1-----Ins2---Ins3---Ins4-
Medicaid-Medicare-------------
---------Medicaid-----No 485--
Blue Cross--------------------
-------Home Health----Medicare
Table I need to construct:
--Column1--
-Medicaid--
-----------
Blue Cross-
-----------
-Medicare--
-Medicaid--
-----------
Home Health
-----------
-----------
-----------
-----------
-----------
--No 485---
-----------
-Medicare--
Maybe my logic is wrong. This is the only way I could see to find unique information across the entire table.

If this is SQL Server, then it sounds like you need to use UNPIVOT to perform this transformation.
Sample UNPIVOT (See SQL Fiddle with Demo):
select ques, answer
FROM t1
unpivot
(
answer
for ques in (col1, col2, col3, col4)
) u
The UNPIVOT will transform your data from columns to rows.

Related

MS Access - trying to find duplicates across 4 tables based on Column1 and Column2

MS Access - trying to find duplicates across 4 tables based on the info in Column1 and Column2. I would also like the resulting query to show me Column3, Column4 and Column5 for easy review. I've tried following a Youtube vid on a union query and was successful.. But that's as far as I can go. I tried to follow along some of the answers but I cant make it work. Just note that I have 0 programming language knowledge. Tyvm in advance!
Column1 = Unique reference
Column 2 = Loss date
Duplicates happen when a row has same unique ref and same DOL. This can be within the table or across tables. Like one entry is in Table2019 and another one is in Table2022. Or two entries in Table2019 with four more spread in other tables.
SELECT [t2019].ID, [t2019].[ClaimNo], [t2019].DOL, [t2019].[Amount], [t2019].[Cause], [t2019].[Ref], [t2019].[Regn], [t2019].Remarks
FROM [t2019]
UNION
SELECT [t2020].ID, [t2020].[ClaimNo], [t2020].DOL, [t2020].[Amount], [t2020].[Cause], [t2020].[Ref], [t2020].[Regn], [t2020].Remarks
FROM [t2020]
UNION
SELECT [t2021].ID, [t2021].[ClaimNo], [t2021].DOL, [t2021].[Amount], [t2021].[Cause], [t2021].[Ref], [t2021].[Regn], [t2021].Remarks
FROM [t2021]
UNION
SELECT [t2022].ID, [t2022].[ClaimNo], [t2022].DOL, [t2022].[Amount], [t2022].[Cause], [t2022].[Ref], [t2022].[Regn], [t2022].Remarks
FROM [t2022];
Access has a wizard to help write the relatively difficult SQL for finding duplicate records. So first gather up all the records that need to be searched for duplicates then use the wizard.
To gather the records open the query designer, go to the SQL Pane, SELECT union and adapt the following SQL:
Unfortunately, there is no graphical interface to help.
Get Typing and don't forget that semi-colon. UNION is used to combine SELECT statements. So were combining everything from all the tables. the ALL is important because by itself UNION ignores rows where every column is an exact match to a previous row. We are looking for duplicates so we add ALL to include those skipped rows.
When you have all the rows go to query wizard under the create tab and run the find duplicates wizard:
Here is the resulting SQL for my example data:
SELECT Query1.[ID], Query1.[DOL], Query1.[ClaimNo], Query1.[Amount], Query1.[Cause], Query1.[Ref], Query1.[Regn], Query1.[Remarks]
FROM Query1
WHERE (((Query1.[ID]) In (SELECT [ID] FROM [Query1] As Tmp GROUP BY [ID],[DOL] HAVING Count(*)>1 And [DOL] = [Query1].[DOL])))
ORDER BY Query1.[ID], Query1.[DOL]
Note:
In Access ID is a primary key and AutoNumber by default. It looks suspicious here. If the default settings are intact and you are entering data in Access then every table starts with ID 1 and you have duplicate ID's in every table. Instead, I would normally combine all these year tables using a year column. This also avoids the union query. I would only use year tables if I had millions of records and couldn't afford the space for a year column.

SQL: Combine tables and order all rows / Avoid storing lots of null data

Typically in SQL JOINS requires you to join two tables ON a specific column, and then rows get merged. That isn't what I'm looking for.
Is it possible to join tables in SQL in a way that you can ORDER BY columns with the same name, such that x rows are returned, where x = the sum of rows in table 1 and table 2.
To hopefully clarify what I mean, here's an example query:
SELECT * FROM (combined Real and Placeholder items)
ORDER BY StartDate, OnDayIndex
and here's what results might look like:
ID OnDayIndex StartDate ItemType Name TemplatePointer
12308 2 1996-09-18 Real Actual Name Null
10309 11 1996-09-19 Placeholder Null 123
30310 5 1996-09-20 Real Actual Name Null
30410 6 1996-09-20 Placeholder Null 456
My use case is a calendar application with recurring events. To save space, it doesn't make sense to store every recurrence of an event. If it weren't for the particulars of my use case I'd just store a template with a rule and recurring events would be generated when viewed, except for one-off events. The problem is the calendar app I'm working on allows you to move items around in the day they're and saves way you order the items. I'm already using a ranked model gem (link here: https://github.com/mixonic/ranked-model) to cut down on the number of writes needed to update the "onDayIndex". The template approach on its own turns into a bit of a nightmare when "onDayIndex" is factored in... (I could say more...)
So I'd like to store slimmed down 'Placeholder' items that store the items' position and a pointer to template, perhaps in a separate table if possible.
If this isn't possible, an alternative approach I've considered for conserving space is moving most columns from the Items table to an ItemData table, and storing an ItemDataID on Items.
But I'd really like to know if it is possible, as I'm pretty junior in SQL, as well as any other vital information I may be missing.
I'm using Rails with a Postgres database.
Are you talking about using UNION / UNION ALL to stack result sets on top of each other, but where the sources have different columns?
If so, you need to fill in the 'missing' columns (you can only UNION two sets if their signatures match, or can be coerced to match).
For example...
SELECT col1, col2, NULL as col3
FROM tbl1
UNION ALL
SELECT col1, NULL AS col2, col3
FROM tbl2
Note: UNION expends additional resources to remove duplicates from the results. Use UNION ALL if such effort is wasted.

How to update numerical column of one table based on matching string column from another table in SQL

I want to update numerical columns of one table based on matching string columns from another table.i.e.,
I have a table (let's say table1) with 100 records containing 5 string (or text) columns and 10 numerical columns. Now I have another table that has the same structure (columns) and 20 records. In this, few records contain updated data of table1 i.e., numerical columns values are updated for these records and rest are new (both text and numerical columns).
I want to update numerical columns for records with the same text columns (in table1) and insert new data from table2 into table1 where text columns are also new.
I thought of taking an intersect of these two tables and then update but couldn't figure out the logic as how can I update the numerical columns.
Note: I don't have any primary or unique key columns.
Please help here.
Thanks in advance.
The simplest solution would be to use two separate queries, such as:
UPDATE b
SET b.[NumericColumn] = a.[NumericColumn],
etc...
FROM [dbo].[SourceTable] a
JOIN [dbo].[DestinationTable] b
ON a.[StringColumn1] = b.[StringColumn1]
AND a.[StringColumn2] = b.[StringColumn2] etc...
INSERT INTO [dbo].[DestinationTable] (
[NumericColumn],
[StringColumn1],
[StringColumn2],
etc...
)
SELECT a.[NumericColumn],
a.[StringColumn1],
a.[StringColumn2],
etc...
FROM [dbo].[SourceTable] a
LEFT JOIN [dbo].[DestinationTable] b
ON a.[StringColumn1] = b.[StringColumn1]
AND a.[StringColumn2] = b.[StringColumn2] etc...
WHERE b.[NumericColumn] IS NULL
--assumes that [NumericColumn] is non-nullable.
--If there are no non-nullable columns then you
--will have to structure your query differently
This will be effective if you are working with a small dataset that does not change very frequently and you are not worried about high contention.
There are still a number of issues with this approach - most notably what happens if either the source or destination table is accessed and/or modified while the update statement is running. Some of these issues can be worked around other ways but so much depends on the context of how the tables are used that it is difficult to provide a more effective generically-applicable solution.

Joining Different Database Tables

I have two tables in Access pulling from databases. There is no primary key linking the two tables, because the databases pull from different programs.
Using SQL, I need all of the information from both tables to pull into a query, and this is where I have problems. The two tables are pulling the same data, but they column titles might not necessarily be the same. For now, I'm assuming they are. How can I get it so that the data from both tables pull into the correct column together?
Here's an example of code (I can't post the real code for certain reasons):
SELECT system1_vehiclecolor, system1_vehicleweight, system1_licenseplate, system2_vehiclecolor, system2_vehicleweight, system2_licenseplate
FROM system1, system2
To further explain this, I want the table to have a column for vehiclecolor, vehicleweight, and licenseplate that combines all of the information. Currently, the way I have it, it is making a column for each of the names in each table, which isn't what I want.
You can use 2 queries to get this done
Select col1as c1 ,col2 col as c2 into resulttable from table1
Insert into resulttable (c1,c2) select colX as c1, colY as c2 from table2
Hope this will help you

Transpose a row into columns with MySQL without using UNIONS?

I have a table that is similar to the following below:
id | cat | one_above | top_level |
0 'printers' 'hardware' 'computers'
I want to be able to write a query, without using unions, that will return me a result set that transposes this table's columns into rows. What this means, is that I want the result to be:
id | cat |
0 'printers'
0 'hardware'
0 'computers'
Is this possible in MySQL? I can not drop down to the application layer and perform this because I'm feeding these into a search engine that will index based on the id. Various other DBMS have something like PIVOT and UNPIVOT. I would appreciate any insight to something that I'm missing.
Mahmoud
P.S.
I'm considering re-normalization of the database as a last option, since this won't be a trivial task.
Thanks!
I got this out of the book The Art of SQL, pages 284-286:
Let's say your table name is foo.
First, create a table called pivot:
CREATE Table pivot (
count int
);
Insert into that tables as many rows as there are columns that you want to pivot in foo. Since you have three columns in foo that you want to pivot, create three rows in the pivot table:
insert into pivot values (1);
insert into pivot values (2);
insert into pivot values (3);
Now do a Cartesian join between foo and pivot, using a CASE to select the correct column based on the count:
SELECT foo.id, Case pivot.count
When 1 Then cat
When 2 Then one_above
When 3 Then top_level
End Case
FROM foo JOIN pivot;
This should give you what you want.
After some fairly extensive digging I stumbled on this page which may or may not contain your answer. It's a difficult in MySQL but from a conceptual point of view I can construct a query that would transpose like this using describe (though it would probably perform horribly). So I'm sure that we can figure out a way to do it the right way.