Creating a SQL view that contains columns which have different data types - sql

I am trying to create a SQL view which contains columns from different tables; the columns are different data types.
For example;
I have table a with a column that contains usernames. The data type of this column is nvarchar.
I then have table b, which has a column that contains whether a document was printed in colour or not – the data is either yes or no. The data type of this column is bit.
I want the view to show both the above columns side by side, so I can then pull the information into Excel for reporting purposes.
I am pretty new to SQL so I am learning as I go along.

Like PM77-1 said, you'll have to have some way to tie the two tables together. For example, if your table b also has the userID of the person who printed the document out, your tables would look like this:
Table A Table B
---------------------------- -----------------------------------
userID userName docID docName inColor userID
---------------------------- -----------------------------------
1 userName1 1 docName1 1 1
2 userName2 2 docName2 0 2
3 userName3 1 docName1 1 2
3 docName3 0 1
3 docName3 1 2
2 docName2 1 3
and your query could look like this:
SELECT a.userName, b.docName, b.inColor FROM a INNER JOIN b ON a.userID = b.userID ORDER BY a.userName, b.inColor;

Related

Is there a way to return a partial blank row in SQL when joining tables through automation?

For my project, I have 2 tables. Initially I inner joined both tables (table 1 and 2) via an inner join. However, I wanted an outcome as seen in table 4 where the repeated value from table 1 is left blank instead.
For table 2, the number of rows will always vary. There will always only be 1 department ID attached to numerous function IDs. Is there a query then where regardless of the number of function IDs, the department ID will only appear as the first row as seen in table 4?
(I think to many, this might seem weird and frankly not clean data, but for mail merges within word, it is easier to field code when the data is presented this way to refrain sections from 'reprinting itself'.)
Current Code:
SELECT Table1.*, Table2.* FROM
INNER JOIN Table 2 ON Table1.DepartmentID = Table2.DepartmentID
Table 1:
Department ID
Department
1
XYZ
Table 2:
Department ID
Function ID
Function
1
1
ABC
1
2
DEF
Table 3 (inner joined):
Department ID
Department
FunctionID
Function
1
XYZ
1
ABC
1
XYZ
2
DEF
Table 4 (desired):
Department ID
Department
FunctionID
Function
1
XYZ
1
ABC
2
DEF

How to display data in SQL from multiple tables, but only if one column data matches another column?

I'm still learning SQL, so this may just be my ignorance or inability to express in a search what I'm looking for. I've spent roughly an hour searching for some variation of the title (both here and general searches on Google). I apologize, I apparently also don't know how to format here. I'll try to clean it up now that I've posted.
I have a database of customer data that I did not design. In the GUI, there are multiple tabs, and it seems like each tab earned it's own table. The tables are linked together with a field called RecordID. In one of the tables is the Customer Data tab. The way that it's organized is that a single customer record from table A can have multiple rows in table B. I only want data from column B in table B is "CompanyA" and if column A in table B = 1. Sample data is below.
Expected output:
CardNumber LastName FirstName CustomerID DataItem
------------------------------------------------------
32154 Clapton Eric 181212 CompanyA
Table A:
RecordID CardNumber LastName FirstName CustomerID
---------------------------------------------------------------
1 12345 Smith John 190201
2 12346 Jones Sandy 190202
3 23456 Petty Tom 190203
4 32154 Clapton Eric 181212
5 14728 Tyler Steven 180225
Table B:
RecordID DataID DataItem
--------------------------------
1 0 CompanyA
1 1 Yes
1 2 No
1 3 Revoked
1 4 NULL
1 5 CompanyB
2 0 CompanyB
2 1 Yes
2 2 No
2 3 NULL
2 4 24-54A
2 5 CompanyC
3 0 CompanyA
3 1 No
3 2 No
3 3 NULL
3 4 68-69B
3 5 NULL
4 0 CompanyA
4 1 Yes
4 2 Yes
5 0 CompanyB
5 1 No
5 2 No
5 5 CompanyA
The concept you're looking for is a JOIN. In this case specifically you need an INNER JOIN. Joins connects two tables together based on criteria you specify (such as matching values in fields) and merges the result into one table in the output.
Here's an example to suit your scenario:
SELECT
A.CardNumber,
A.LastName,
A.FirstName,
A.CustomerID,
B.DataItem
FROM
TableA A
INNER JOIN TableB B -- join tableB onto tableA
ON A.RecordID = B.RecordID -- in the ON clause you specify criteria by you match the fields
WHERE
B.columnA = 'CompanyA'
AND B.columnB = 1
Here's the relevant SQL Server Documentation
Also I'd advise you to potentially take a comprehensive introductory SQL tutorial, and/or find a book. A good one will introduce all of the basic, key concepts such as this to you in a logical way, then you're not grasping in the dark trying to google things for which you don't know the correct terminology.
select a.CardNumber, a.LastName, a.FirstName, a.CustomerID, b.dataitem
from tableA A inner join TableB b
on a.recordid = b.recordid
where b.columnA= 'CompanyA' and b.columnB = 1
Here is your solution,
select a.CardNumber, a.LastName, a.FirstName, a.CustomerID, b.DataItem from
tableA a
inner join tableB b
on (a.RecordID = b.RecordID)
where
b.DataItem='CompanyA'
b.RecordID=1;
Le me know if the result is not as expected
Your question is quite hard to understand, but let me give you an example that resembles the what i think you are asking.
SELECT a.*, b.DataItem FROM A a INNER JOIN B b
ON a.RecordID = b.RecordID AND
b.DataItem = `CompanyA`
At the database engine level, if you are using Microsoft technology, the most efficient structure is to use an indexed foreign key constraint on Table B, and a Primary Surrogate Key (PSK) column on Table A. The Primary Surrogate Key in your case is on the Parent table, Table A, and is called RecordID. The foreign key column with the FKC is on Table B, on the column named RecordID. Once you verify that there is a FKC (foreign key constraint on Table B, which pins both columns named RecordID between both tables on matched values), then address the GUI. At the GUI, between the tabs, you generally indicate you have a parent table with a unique set of Record IDs (one column named Record ID with absolutely unique values in each row and no empty rows on that column). There will also be child tables on each Tab in your GUI, and those are bound to the parent table in a "1 to Many (1:M)" fashion, where 1 parent has many children. Your commentary or question indicates that you also want to filter, where Record ID on the child in one of the related tabs equates to the integer value 1 on the Record ID. So, there needs to be a query somewhere:
SELECT [columns]
FROM [Table B]
INNER JOIN [Table A]
ON A.RecordID = B.RecordID
AND B.RecordID = 1;
Does that help?

SQL - Linking two tables

I have two tables, specifically, they contain standard and specific parameters respectively.
Table1:
PKParameter Name Unit
1 Temperature K
2 Length mm
3 Pressure bar
Table2:
PKSpecParam Name Unit
1 Weight kg
2 Area m2
PKParameter ans PKSpecParameter are primary keys
I would like to combine these two tables into a third table which will keep track of the primary keys so I can reference any of the parameters, regardless of the table they are from.
For example:
PKCombined PKParameter PKSpecParameter
1 1 NULL
2 2 NULL
3 3 NULL
4 NULL 1
5 NULL 2
Now I would like to use PKCombined primary key to reference parameter
Maybe there is a better way to do this, but I've just started meddling with databases.
Select a.PKParameter , a.name,a.unit,b.PKSpecParam , b.name,b.unit
from table1 a outer join table2 b on a.pkparameter=b.pkspecparam
However, this will give out null values if number of entries in pkparameter and pkspecparam dont match

Getting matching attributes from two tables

I have two tables looking like this:
A B
id_attr value id id_attr value
-------------- -------------------
1 a 1 2 b
2 b 1 3 c
3 c 2 2 b
4 NULL 2 4 d
2 5 e
3 1 aaa
3 3 c
Table A is my reference table and I have multiple entries in table B. (every group of entries with the same id cosists of pairs of (id_attr,value) similiar to structure of table A). Goal is to check if entry in table A matches any of the entries in table B (one or more). One entry matches another when every attribute existing in table B under one id matches similiar attributes in table A. Also, in table A values could be NULL, but in table B not.
In example above my query should return "1", becouse only entries with id 1 fully match similiar entries in table A. Id 2 doesn't match, becouse in table A value of attribute 4 is NULL and it has an attribute which doesn`t exist in table A. Id 3 doesn't match either even if attribute 3 is similiar, but attribute 1 doesn't match.
As you can see to achieve a match not every one of the entries existing in table A should be matching, but if an attribute exists in table B then it value has to match similiar value in table A.
What is the most efficient way to achieve this result in an Oracle query?
Every help would be greatly appreciated. I can provide answers to further questions if I didn't express myself clear enough.
You can try the following:
SELECT ID, MIN(IS_OK) FROM
(
SELECT B.ID ID,
DECODE(B.VALUE, A.VALUE, 'Y', 'N') IS_OK
FROM A INNER JOIN B
ON B.ID_ATTR = A.ID_ATTR
)
GROUP BY ID;
Which will return you B's ID and a flag that indicates whether this ID is OK or not.
(Note that Decode will properly take care of the null values comparison without having to test for null values)

Normalise/join SQL Server tables

I have inherited a SQL server database which isn't normalised and is giving me headaches. I am not very experienced in SQL and maybe asking stupid questions but would appreciate any advice on how to go forward with the below scenarios.
I have three tables as follows:-
A table of results:
**ResId CompId Name Result**
1 1 Band A 2
2 1 Band B 1
3 1 Band C 3
4 2 Band A* 2
5 2 Band B 1
6 2 Band C 3
A table of Bands current names:
**BandId BandName**
1 Band A
2 Band B
3 Band C
A table of names the bands were previously known as (linked on BandId):
**oldBandId BandId oldBandName**
1 1 Band A*
2 1 Band a
2 2 Band b
I am looking to consolidate the list of band names in the results table, replacing the band name with a bandId however the result table contains band names from both tables. First question should I create some sort of join table and use this as the bandId in the results table? If so What do I need in this join table, is it just a psuedo-Id of bandId/oldBandId and the table name concatenated then this placed in the results table?
I am then looking to use a query to select all results where the user selects the band by any name variant (new or old) and returns the results including all names linked with the band i.e. choosing Band A would return the results for both Band A and Band A*.
Thanks in advance
Steve
I like the idea of using the band id in the results table. I would suggest eliminating the "old band name" table and replace it with a table of band aliases, since that sounds more like what you want. The band alias table would just have the band id and an one alias per row.
I think your current db structure is fine enough - I can't think of any way to improve on it, without complicating it further (especially if you want to retain the old band names).
You can just write a query as so for your need -
select * from results
where Name = #bandName or
Name in (select oldBandName
from oldBands
where BandId in (select BandId
from Bands
where BandName = #bandName))