Whilh SQL Structure Is Better? - sql

I have 2 Option For Creating a SQL stucture
For example I need column Code, Name, and Religion :
Option 1 :
+=======+========+=============+
+ Code + Name + Religion_id +
+=======+========+=============+
+ 1 + A + 1 +
+ 2 + B + 2 +
+ 3 + c + 2 +
+=======+========+=============+
+=============+===============+
+ Religion_id + religion_name +
+=============+===============+
+ 1 + Caaaaaa +
+ 2 + Daaaaaa +
+=============+===============+
Option 2 :
+=======+========+
+ Code + Name +
+=======+========+ For Master File
+ 1 + A +
+ 2 + B +
+ 2 + C +
+=======+========+
+=============+===============+
+ Religion_id + religion_name +
+=============+===============+ For Master File
+ 1 + Caaaaaa +
+ 2 + Daaaaaa +
+=============+===============+
+=======+=============+
+ Code + Religion_id +
+=======+=============+ For Transaction File
+ 1 + 1 +
+ 2 + 2 +
+ 3 + 2 +
+=======+=============+
I have done database for around 1 year.
But after I learned at college, I learned that in master file cannot have duplicate data.
In Option 1 there is a duplicate value such as 2 people with same religion. So They create the structure like Option 2.
but IMO Option 2 will take a lot of memory space with a thousand records than Option 1.
My Question is : Which One is the best practice for creating the SQL Structure?
EDit: 1 Name can only has 1 religion

It depends on the relationship between the two tables.
Option 1 is a One-to-many Relationship wherein Religion can contain on many Names. But if the relationship is Many-to-Many, wherein a certain Name can have multiple Religions and that religion can be on many Name, go for Option 2 since it uses association table.

Related

SQL invalid Identifier query

I am getting an error that grandvisit is an invalid identifier, and I am unsure if I will get it with other identifiers either. Any light shed on this would be amazing. As I cannot see why it differents from others.
You cannot refer the alias names in same select clause where it is generated.
SELECT Sum(aerosolvisit + hazvisit + hvvisit + hlopvisit
+ plvisit + miniloadvisit + aprvisit + apr2visit
+ aprawkvisit) AS grandvisit
To calculate grandratio you are using the below expression which uses the alias name grandvisit
SELECT CASE
WHEN Sum(grandtotal) = 0 THEN 0
WHEN Sum(grandvisit) = 0 THEN 0
ELSE Sum(grandtotal) / Sum(grandvisit)
END AS grandratio
You can use derived table to do this
SELECT CASE
WHEN Sum(grandtotal) = 0 THEN 0
WHEN Sum(grandvisit) = 0 THEN 0
ELSE Sum(grandtotal) / Sum(grandvisit)
END AS grandratio
From
(
SELECT Sum(aerosolvisit + hazvisit + hvvisit + hlopvisit
+ plvisit + miniloadvisit + aprvisit + apr2visit
+ aprawkvisit) AS grandvisit
...
) A
Note : You are using old style outer join's(+=). It is better to use Right/Left joins which is more readable

SQL joins with mulitple where conditions

I have one table that looks like this:
[Jobs]
+-----+-------+---------+
+ ID + Title + Active +
+-----+-------+---------+
+ 1 + Admin + 0 +
+-----+-------+---------+
+ 2 + Mgr + 1 +
+-----+-------+---------+
+ 3 + Emp + 0 +
+-----+-------+---------+
[JobsTxt]
+-------+-------+---------+
+ JobID + Text + Type +
+-------+-------+---------+
+ 1 + test + 1 +
+-------+-------+---------+
+ 1 + test2 + 1 +
+-------+-------+---------+
+ 1 + test3 + 2 +
+-------+-------+---------+
+ 3 + test + 1 +
+-------+-------+---------+
I want to write a query that gives me the Text entries from the JobsTxt table that have Type= 1 and Active=0 in the Jobs table, where JobsTxt.JobID = Jobs.ID
So it'd be something like:
Select [JobsTxt].Text from [JobsText] left join [Jobs] on [JobsTxt].JobId = [Jobs].ID where [JobsTxt].Type = 1 and [Jobs].Active = 0
I'm very new to joins and queries like this, so any help is appreciated!
EXISTS are good if you dont require a JOIN, meaning you only need fields from one of the tables.
SELECT jt.Text
FROM [JobsText] jt
WHERE jt.Type = 1
AND EXISTS
(
SELECT 1
FROM [Jobs] j
WHERE j.ID = jt.JobID
AND j.Active = 0
);
Please excuse, I am not allowed to comment directly on your question. So, let me just put it here, even as I think this may not qualify as an answer.
To me, your SQL statement looks perfectly okay and should deliver what you described. Maybe you could help us out and give some information on the SQL dialect involved (i.e., what database system you are running and what version)?
edit:
it seems you do have a typo:
[...] from [JobsText] [...]
↑ - should there be an 'e'?
Thank you.
Please make use of below query:
DECLARE #Jobs TABLE (ID INT, Title VARCHAR(10), Active BIT )
INSERT INTO #Jobs VALUES
(1,'Admin',0),
(2,'Mgr',1),
(3,'Emp',0)
DECLARE #Jobtxt TABLE ( JobID INT, [Text] VARCHAR(10), [Type] INT)
INSERT INTO #Jobtxt VALUES
(1,'test',1),
(1,'test2',1),
(1,'test3',2),
(3,'test',1)
SELECT
Jt.JobID,Jt.[Text]
FROM
#Jobtxt Jt INNER JOIN #Jobs J ON Jt.JobID = J.ID
WHERE
J.Active = 0 AND Jt.[Type] =1

Ordering SQL SELECT by result of a string comparison

I have a table with two string columns, ID and LANGUAGE. Language can be one of CYM, ENG, GAE.
When selecting data from the table, I want to order it by the language column, putting a specified language at the start of the results, with the other languages later, in any order.
Say I have the data
+===+=====+
+ 1 + CYM +
+ 2 + GAE +
+ 3 + ENG +
+ 4 + CYM +
+===+=====+
and I want the output to be
+===+=====+
+ 3 + ENG +
+ 1 + CYM +
+ 2 + GAE +
+ 4 + CYM +
+===+=====+
How do I do the equivalent of
SELECT ID, LANGUAGE
FROM TABLE
ORDER BY (LANGUAGE = 'ENG'), ID
You can use CASE WHEN to ensure ENG will be first:
SELECT ID, LANGUAGE
FROM your_table
ORDER BY
CASE LANGUAGE WHEN 'ENG' THEN 0
ELSE 1
END ASC;
-- ,ID ASC -- if needed
LiveDemo

How to combine two sql queries into one

How can I combine these two SQL statements?
SELECT SUM(hits01 + hits02 + hits03 + hits04 + hits05 + hits06 + hits07 + hits08 + hits09) AS 'AEROwiz'
FROM tbl_2011
WHERE appName='AEROwiz'
SELECT SUM(hits10 + hits11 + hits12) AS 'AEROwiz'
FROM tbl_2010
WHERE appName='AEROwiz'
hits10, hits11 and hits12 exist in both tables.
Use a UNION query - just stuff "UNION" between the two queries:
SELECT SUM(...) AS AEROWiz
FROM ...
UNION
SELECT SUM(...) AS AEROWiz
FROM ...
update
wrap the union in yet another query:
SELECT SUM(AEROWiz)
FROM (
.... unioned queries here
) AS child
SELECT SUM(hits01 + hits02 + hits03 + hits04 + hits05 + hits06 +
hits07 + hits08 + hits09) AS 'AEROwiz'
FROM tbl_2011
WHERE appName='AEROwiz'
UNION ALL
SELECT SUM(hits10 + hits11 + hits12) AS 'AEROwiz'
FROM tbl_2010
WHERE appName='AEROwiz'
Use UNION ALL as it will allow duplicates, and UNION will not put duplicates in the query result. With the SUM() aggregate, I'm guessing there's a good chance of duplication summations, so I'd go with UNION ALL for this one.
You could use two subselects:
SELECT
(
SELECT SUM(hits01 + hits02 + hits03 + hits04 + hits05 + hits06 + hits07 + hits08 + hits09)
FROM tbl_2011
WHERE appName='AEROwiz'
) T1
+
(
SELECT SUM(hits10 + hits11 + hits12)
FROM tbl_2010
WHERE appName='AEROwiz'
) T2
AS AEROwiz
You may also want to consider normalizing your database so that you don't have a table for each year.
SELECT SUM(hits01 + hits02 + hits03 + hits04 + hits05 + hits06 +
hits07 + hits08 + hits09 + t2010.hits10 + t2010.hits11 + t2010.hits12) AS 'AEROwiz'
FROM tbl_2010 t2010
JOIN tbl_2011 t2011 ON t2010.appName = t2011.appName
WHERE t2010.appName='AEROwiz'

Complex SQL CASE WHEN

I am trying to do a SELECT using a CASE statement, and I 'm getting errors that do not make sense. My statement appears to adhere to any SQL syntax rules but I'm getting the good ol' "the multi part identifier to_do.[item_id] AND to_do.[item] cannot be bound.
This does not make sense because the column names are correct with respect to the table columns.
Here is the SQL:
SELECT to_do.[item_id],
to_do.[item] = CASE to_do.encounter_id WHEN 0 THEN CONVERT(NVARCHAR, e.[date], 101 ) + ' - ' + p.[first_name] + ' ' + p.[last_name] + ' - ' + to_do.[item] AS to_do.[item] ELSE to_do.[item] END,
to_do.[complete],
to_do.[encounter_id],
e.[date],
p.[last_name] + ', ' + p.[first_name] AS [p_name]
FROM [dbo].[to_do] LEFT OUTER JOIN
[dbo].[encounter] e ON
to_do.[encounter_id] = e.[encounter_id] LEFT OUTER JOIN
[dbo].[patients] p ON
e.[mrn] = p.[mrn]
WHERE to_do.[user_id] = #user_id
Any ideas what I'm doing wrong here ? Based off previous experience I should be able to use CASE like this but maybe I've just been staring at it too long and don't see the obvious.
Thanks!
You can't use a table prefix in a column alias to_do.[item] = CASE ... is presumably intended to be [item] = CASE ...
(Also you have a rogue AS in the middle of the CASE itself that needs removing)
The AS {alias} needs to go after the END. I'd rewrite as follows:
SELECT to_do.[item_id],
CASE to_do.encounter_id WHEN 0 THEN CONVERT(NVARCHAR, e.[date], 101 ) + ' - ' + p.[first_name] + ' ' + p.[last_name] + ' - ' + to_do.[item] ELSE to_do.[item] END AS [item] ,
...
Your AS is in the wrong place-- try
to_do.[item] = CASE to_do.encounter_id WHEN 0 THEN CONVERT(NVARCHAR, e.[date], 101 ) + ' - ' + p.[first_name] + ' ' + p.[last_name] + ' - ' + to_do.[item] ELSE to_do.[item] END AS to_do.[item] ,