Selecting description based on 3 int columns - sql

I have a table with the fields ID,department_code,sub_department_code,class_code,desc_text
The desc_text has the name of the department when the sub_department_code and class_code fields are null, the sub_department name when the department_code and sub_department_code are not null but class_code is null, and the name of the class when the class_code is not null.
My issue is I have another table that has the id from the table above, but I would like to select the fields with department_code,desc_text(of the department),sub_department_code,desc_text(of the sub_department), etc.
I tried a few methods, but I am unsure even how to search for this issue.
I have the following two tables:
Hierarchy
id,department_code,subdept_code,class_code
1 1 null null
2 1 1 null
3 1 1 1
4 2 1 null
Hierarchy_detail
id,hierarchy_id,short_text
1 1 car
2 2 truck
The hierarchy.id is linked to hierarchy_detail.hierarchy_id
With this, I have a table that has data I want, which the fk from hierarchy.id, which I cna link and get the department, sub-sept and class codes, but I am having trouble getting the text on there for each type.

You want to use a case statement to capture the logic. If Im' reading correctly, it looks something like this:
select id, department_code, sub_department_code, class_code,
(case when sub_department_code is null and class_code is null
then desc_text
end) as department_name,
(case when department_code is not null and sub_department_code is not null and class_code is null
then desc_text
end) as sub_department_name,
(case when class_code is not null then desc_text
end) as class_name
from t
You can then use this query as a subquery to join to other tables.

Related

How to get id of parent tables which haven't any foreign key with another table

I have a structure of a table have many fields
table_id
name_table
name_filed
PK
FK
1
person
id
pk
1
person
name
1
person
age
2
dog
id
pk
2
dog
name
2
dog
owner
fk
3
phone
id
pk
3
phone
name
3
phone
owner
fk
How to get id(s) of parent tables which haven't any foreign key with another table
in this case expected result is 1
I've tried
select distinct table_id from tables_structure where fk!=''
Also I've tried with group by
select table_id from tables_structure where fk!=''
group by table_id
having fk!=''
The first issue is that you are comparing to an empty string, generally we expect the empty value to be represented by a null value, so try comparing using IS NULL
select distinct table_id from tables_structure where fk IS NULL
But that isn't likely to help you here, your data represents an UNPIVOT structure, your second attempt would work if you used a COUNT in your HAVING clause, here we don't even have to compare nulls because COUNT will exclude nulls for us!
select table_id
from tables_structure
group by table_id
having COUNT(fk) = 0
If the values really are empty strings, and not nulls, then we can still use count with nulls by treating '' as a null value using NULLIF:
select table_id
from tables_structure
group by table_id
having COUNT(NULLIF(fk,'')) = 0
We can't just filter by fk <> '' as that will modify the dataset and return ALL records.
You can use a SUM over a CASE statement that computes a 1 or 0 for each record, but now things are getting complicated:
select table_id
from tables_structure
group by table_id
having SUM(CASE fk WHEN '' THEN 0 ELSE 1)) = 0

How can I replace the NULL with a value when using an INSERT?

I am trying to find out why this section of the query wouldn't work
ISNULL(nightlyTable.AppointmentID,
baseTable.AppointmentID) AS AppointmentID
Is there another way of writing this section? I need for it to show an AppointmentID when the value is NULL.
Thank you!!
USE [AdventureWorksLT]
GO
SET IDENTITY_INSERT [dbo].[tempTable] ON
INSERT INTO [dbo].[tempTable]
([AppointmentID]
,[CustName]
,[CustAddress]
,[CustPhone])
(SELECT
ISNULL(nightlyTable.AppointmentID,
baseTable.AppointmentID) AS AppointmentID
, nightlyTable.CustName
, nightlyTable.CustAddress
, nightlyTable.CustPhone
FROM nightlyTable
FULL OUTER JOIN baseTable ON (baseTable.AppointmentID =
nightlyTable.AppointmentID)
WHERE EXISTS (SELECT nightlyTable.* EXCEPT SELECT baseTable.*))
GO
SET IDENTITY_INSERT [dbo].[tempTable] OFF;
Sample result. I'd like for row 10 to show AppointmentID '10' instead of NULL.
AppointmentID CustName CustAddress CustPhone
1 Salvad0r 1 Main Street North 76197081653
NULL NULL NULL NULL
3 Gilbert 51 Main Street South 23416310745
NULL NULL NULL NULL
5 Jorge 176 Washington Street 7078675309
NULL NULL NULL NULL
7 Stella 192 Church Street 78584836879
NULL NULL NULL NULL
9 Heyy 214 High Street 57288772686
NULL NULL NULL NULL
11 Newbie 21 Jump Street 76086753019
Sample tables:
This code:
ISNULL(nightlyTable.AppointmentID, baseTable.AppointmentID) AS AppointmentID
does not work because you have no table alias for basetable defined in the FROM clause.
So you want to select all the elements in base table that are not in night table. To do that you left join base table to night table and then look where it was unable to join. Like this:
select b.*
from baseTable b
left join nightlyTable n on n.AppointmentID = b.AppointmentID
where n.AppointmentID is null
If you also want to include existing data in nightly table the easy way is with a union, like this:
select *
from nightlyTable
UNION ALL
select b.*
from baseTable b
left join nightlyTable n on n.AppointmentID = b.AppointmentID
where n.AppointmentID is null

Convert enumerated type and corresponding values into separate column in SQL

I would not be surprised if this is a duplicate, but I have not been able to find this variation on the theme.
I have a table with two columns: one indicates data type, and the other the corresponding value. I want to convert this using SELECT so that each enumerated "type" is its own column populated by the values.
Table PersonInfo
InfoID PersonID AttributeType AttributeValue
1 1 email bob#example.com
2 1 dept research
3 2 email judy#example.com
4 2 dept engineering
5 3 email frank#example.com
The SELECT result will be:
PersonID email dept
1 bob#example.com research
2 judy#example.com engineering
3 frank#example.com NULL
As you can see, the InfoID index is no longer needed.
In my case, I know the potential values in the AttributeType column, so I don't need it to be completely dynamic.
Here is what I tried:
SELECT DISTINCT PersonID,
CASE AttributeType WHEN 'email' THEN AttributeValue ELSE null END as email
CASE AttributeType WHEN 'dept' THEN AttributeValue ELSE null END as dept
I know why this is failing, but I'm not sure what to do to get it to work as I would like.
select
personid,
max(case when attributetype='email' then AttributeValue end) email,
max(case when attributetype='dept' then AttributeValue end) dept
from
table
group by personid

Retrieve one row in select statement which generates multiple rows (by avoiding NULL rows if possible)

I want to get the Name from this table but I only have the Number which is not unique. How do I get the correct Name (please give me some SQL syntax)?
Below the database table you can see the input and expected output for
Database Table
Number Name
1 Anna
1 Anna
2 Brad
2 NULL
2 NULL
2 NULL
3 NULL
3 NULL
4 Adam
5 NULL
Input and expected output:
Number (Input) Name (Expected outpu)
1 Anna
2 Brad
3 NULL
4 Adam
5 NULL
What do I need to add to my query to make it work?
SELECT Name FROM tablename
WHERE Number='chosen number'
A simple MAX/GROUP BY will return your expected result set:
SELECT Number, MAX(Name)
FROM table name
GROUP BY 1;
Btw, NUMBER is a Reserved Name in Teradata
SELECT
number,
MAX(name)
FROM
your_table
GROUP BY
number
And/Or
SELECT
MAX(name)
FROM
your_table
WHERE
number = x
MAX, MIN, etc, all treat NULL as the last value; you only get a NULL if all values are NULL.
This is a step in the right direction, the problem is that you will still get NULL aswell if you have a row with NULL give me a bit to figure out how to filter those out if there is a name
Mysql would be this:
http://sqlfiddle.com/#!9/4beca/1
SELECT DISTINCT Name
FROM mytable
WHERE Number=1 AND Name is not null
UNION
SELECT NULL
FROM mytable
LIMIT 1
SQL-Server would be this:
http://sqlfiddle.com/#!3/f4078/11
SELECT TOP 1 sub.Name
FROM
(SELECT DISTINCT Name
FROM mytable
WHERE Number=1 AND Name is not null
UNION
SELECT NULL AS Name
FROM mytable) AS sub

MySQL Column Value Pivot

I have a MySQL InnoDB table laid out like so:
id (int), run_id (int), element_name (varchar), value (text), line_order, column_order
`MyDB`.`MyTable` (
`id` bigint(20) NOT NULL,
`run_id` int(11) NOT NULL,
`element_name` varchar(255) NOT NULL,
`value` text,
`line_order` int(11) default NULL,
`column_order` int(11) default NULL
It is used to store data generated by a Java program that used to output this in CSV format, hence the line_order and column_order.
Lets say I have 4 entries (according to the table description):
1,1,'ELEMENT 1','A',0,0
2,1,'ELEMENT 2','B',0,1
3,1,'ELEMENT 1','C',1,0
4,1,'ELEMENT 2','D',1,1
I want to pivot this data in a view for reporting so that it would look like more like the CSV would, where the output would look this:
---------------------
|ELEMENT 1|ELEMENT 2| <--- Element Name
---------------------
| A | B | <--- Value From line_order = 0
---------------------
| C | D | <--- Value From line_order = 1
---------------------
The data coming in is extremely dynamic; it can be in any order, can be any of over 900 different elements, and the value could be anything. The Run ID ties them all together, and the line and column order basically let me know where the user wants that data to come back in order. I want it to sort/group by line and column order in the displayed matrix.
You can do that with a self join:
select e1.element_name, e1.value, e2.value
from MyTable e1
inner join MyTable e2
on e1.element_name = e2.element_name
and e2.line_order = 1
where e1.line_order = 0
The from selects line_order = 1, the inner join selects line_order = 2.
Switch inner join to cross join if you'd like to return elements with only one line_order.
In reply to your comment, you could write out a fixed number of elements like:
select
line_order
, max(case when element_name = 'element 1' then value end) as Element1Value
, max(case when element_name = 'element 2' then value end) as Element2Value
, max(case when element_name = 'element 3' then value end) as Element3Value
, ...
from MyTable
group by line_order
The max() construct assumes that (element_name, line_order) is unique.