Compare two columns and return the result in a thrid - sql

Lets say I have this table :
--------------------------------------------------------------------------
| id | allowed_to_play_pokemon_go_after | last_played_pokemon_go | name |
--------------------------------------------------------------------------
| 1 | 20-JUL-16 | 19-JUL-16 | Jhon |
--------------------------------------------------------------------------
| 2 | 19-JUL-16 | 21-JUL-16 | Bill |
--------------------------------------------------------------------------
Now I want to make a select like that :
SELECT name, (last_played_pokemon_go > allowed_to_play_pokemon_go_after) as must_punish
FROM myTable;
Where 'must_punish' has to bo a boolean (1/0).

You can use case:
SELECT name,
(case when last_played_pokemon_go > allowed_to_play_pokemon_go_after then 1 else 0
end) as must_punish
FROM myTable;
Oracle (the database) doesn't have a boolean data type. A number should be fine.

Related

SQL Check if the User has IN and Out

I need help getting the User which has an 'IN' and 'Out' in Column isIN. If the user has an IN and OUT do not select them in the list. I need to select the user who has only had an IN. Please I need help. Thanks in advance.
This is the table:
| Users | IsIN |
|:------------------:|:-----:|
| MHYHDC61TMJ907867 | IN |
| MHYHDC61TMJ907867 | OUT |
| MHYHDC61TMJ907922 | IN |
| MHYHDC61TMJ907922 | OUT |
| MHYHDC61TMJ907923 | IN |
| MHYHDC61TMJ907923 | OUT |
| MHYHDC61TMJ907924 | IN | - I need to get only this row
| MHYHDC61TMJ907925 | IN |
| MHYHDC61TMJ907925 | OUT |
| MHYHDC61TMJ908054 | IN | - I need to get only this row
| MHYHDC61TMJ908096 | IN | - I need to get only this row
| MHYHDC61TMJ908109 | IN | - I need to get only this row
Need to get the result like
| Users | IsIN |
|:------------------:|:-----:|
| MHYHDC61TMJ907924 | IN |
| MHYHDC61TMJ908054 | IN |
| MHYHDC61TMJ908096 | IN |
| MHYHDC61TMJ908109 | IN |
I tried using this query and sample query below but it doesn't work.
select s.[Users], s.[isIn] [dbo].[tblIO] s
where not exists (
select 1
from [dbWBS].[dbo].[tblIO] s2
where s2.[Users] = s.[Users] and s2.isIn = 'IN'
);
You can use not exists:
select s.*
from sample s
where not exists (select 1
from sample s2
where s2.user = s.user and s2.inout = 'OUT'
);
If you want only users that meet the condition (and not the full rows):
select user
from sample s
group by user
having min(inout) = max(inout) and min(inout) = 'IN';
Bearing in mind that an 'OUT' IsIn must be always preceded by an 'IN' record, you could use a query like this:
select s.Users, 'IN' as IsIn
from sample s
group by s.Users
having count(distinct s.IsIn) = 1

SQL GROUPING with conditional

I am sure this is easy to accomplish but after spending the whole day trying I had to give up and ask for your help.
I have a table that looks like this
| PatientID | VisitId | DateOfVisit | FollowUp(Y/N) | FollowUpWks |
----------------------------------------------------------------------
| 123456789 | 2222222 | 20180802 | Y | 2 |
| 123456789 | 3333333 | 20180902 | Y | 4 |
| 234453656 | 4443232 | 20180506 | N | NULL |
| 455344243 | 2446364 | 20180618 | Y | 12 |
----------------------------------------------------------------------
Basically I have a list of PatientIDs, each patient can have multiple visits (VisitID and DateOfVisit). FollowUp(Y/N) specifies whether the patients has to be seen again and in how many weeks (FollowUpWks).
Now, what I need is a query that extracts PatientsID, DateOfVisit (the most recent one and only if FollowUp is YES) and the FollowUpWks field.
Final result should look like this
| PatientID | VisitId | DateOfVisit | FollowUp(Y/N) | FollowUpWks |
----------------------------------------------------------------------
| 123456789 | 3333333 | 20180902 | Y | 4 |
| 455344243 | 2446364 | 20180618 | Y | 12 |
----------------------------------------------------------------------
The closest I could get was with this code
SELECT PatientID,
Max(DateOfVisit) AS LastVisit
FROM mytable
WHERE FollowUp = True
GROUP BY PatientID;
The problem is that when I try adding the FollowUpWks field to the SELECT I get the following error: "The query does not include the specified expression as part of an aggregate function." However, if I add FollowUpWks to the GROUP BY statement than I get all visits, not just the most recent ones.
You need to match back to the most recent visit. One method uses a correlated subquery:
SELECT t.*
FROM mytable as t
WHERE t.FollowUp = True AND
t.DateOfVisit = (SELECT MAX(t2.DateOfVisit)
FROM mytable as t2
WHERE t2.PatientID = t.PatientID
);

How to maintain

I'm wondering if SQL Server (i.e. the T-SQL language) has a natural way of doing this or if I have to write fancy constraints/triggers.
Suppose I have a table
RebuplicanCandidates
===================================
Id | Name | ByteIndex
===================================
1 | 'Marco Rubio' | 0
2 | 'Jeb Bush' | 1
3 | 'Donald Trump' | 2
4 | 'Ted Cruz' | 3
and I remove JebBush:
DELETE FROM [RepublicanCandidates] WHERE [Id]=2
Then I want the table to be like
RebuplicanCandidates
===================================
Id | Name | ByteIndex
===================================
1 | 'Marco Rubio' | 0
3 | 'Donald Trump' | 1
4 | 'Ted Cruz' | 2
Notice that the ByteIndex column shuffled.
And then if I insert a candidate
INSERT INTO [RepublicanCandidates] (Name) VALUES ('CarlyFiorina')
the table becomes
RebuplicanCandidates
===================================
Id | Name | ByteIndex
===================================
1 | 'Marco Rubio' | 0
3 | 'Donald Trump' | 1
4 | 'Ted Cruz' | 2
5 | 'Carly Fiorina' | 3
If you created a VIEW based on the table, you could add a row_number() function, and drop the ByteIndex column from the base table.
CREATE VIEW vRebuplicanCandidates
AS
SELECT id, name , ROW_NUMBER() OVER (ORDER BY id) - 1 AS ByteIndex
FROM RebuplicanCandidates
T-SQL cannot do what your are asking. You will have to write some code or the suggestion in the other answer by is a good one IMHO.

SQL for calculated column that chooses from value in own row

I have a table in which several indentifiers of a person may be stored. In this table I would like to create a single calculated identifier column that stores the best identifier for that record depending on what identifiers are available.
For example (some fictional sample data) ....
Table = "Citizens"
Id | LastName | DL-No | SS-No | State-Id-No | Calculated
------------------------------------------------------------------------
1 | Smith | NULL | 374-784-8888 | 7383204848 | ?
2 | Jones | JG892435262 | NULL | NULL | ?
3 | Trask | TSK73948379 | NULL | 9276542119 | ?
4 | Clinton | CL231429888 | 543-123-5555 | 1840430324 | ?
I know the order in which I would like choose identifiers ...
Drivers-License-No
Social-Security-No
State-Id-No
So I would like the calculated identifier column to be part of the table schema. The desired results would be ...
Id | LastName | DL-No | SS-No | State-Id-No | Calculated
------------------------------------------------------------------------
1 | Smith | NULL | 374-784-8888 | 7383204848 | 374-784-8888
2 | Jones | JG892435262 | NULL | 4537409273 | JG892435262
3 | Trask | NULL | NULL | 9276542119 | 9276542119
4 | Clinton | CL231429888 | 543-123-5555 | 1840430324 | CL231429888
IS this possible? If so what SQL would I use to calculate what goes in the "Calculated" column?
I was thinking of something like ..
SELECT
CASE
WHEN ([DL-No] is NOT NULL) THEN [DL-No]
WHEN ([SS-No] is NOT NULL) THEN [SS-No]
WHEN ([State-Id-No] is NOT NULL) THEN [State-Id-No]
AS "Calculated"
END
FROM Citizens
The easiest solution is to use coalesce():
select c.*,
coalesce([DL-No], [SS-No], [State-ID-No]) as calculated
from citizens c
However, I think your case statement will also work, if you fix the syntax to use when rather than where.

How to check date in postgresql

my table name is tbl1. The fileds are id,name,txdate.
| ID | NAME | TXDATE |
| 1 | RAJ | 1-1-2013 |
| 2 | RAVI | |
| 3 | PRABHU | 25-3-2013 |
| 4 | SAT | |
Now i want to use select query for check txdate < 2-2-2013 in which rows have txdate not empty and the select also retrun which rows have txdate empty.
The Result is like this
| ID | NAME | TXDATE |
| 1 | RAJ | 1-1-2013 |
| 2 | RAVI | |
| 4 | SAT | |
Any feasible solution is there?.
With out using union it is possible?.
Assuming that the TXDATE is of data type DATE then you can use WHERE "TXDATE" < '2013-2-2' OR "TXDATE" IS NULL. Something like:
SELECT *
FROM table1
WHERE "TXDATE" < '2013-2-2'
OR "TXDATE" IS NULL;
See it in action:
SQL Fiddle Demo
I don't now what database your are using and what data type the TXDATE is.
I just tried on my postgreSQL 9.2, with a field "timestamp without time zone".
I have three rows in the table , like:
ac_device_name | ac_last_heartbeat_time
----------------+-------------------------
Nest-Test1 |
Nest-Test3 |
Nest-Test2 | 2013-04-10 15:06:18.287
Then use below statement
select ac_device_name,ac_last_heartbeat_time
from at_device
where ac_last_heartbeat_time<'2013-04-11';
It is ok to return only one record:
ac_device_name | ac_last_heartbeat_time
----------------+-------------------------
Nest-Test2 | 2013-04-10 15:06:18.287
I think you can try statement like:
select * from tbl1 where TXDATE<'2-2-2013' and TXDATE is not NULL
this statement also works in my environment.