Compare columns in 2 SQL tables - c#

I am trying to write my first c# app. And don't know how to compare 2 columns to calculate another field
This is table 1 (Prediction table):
Col A Col B
--------------------------------------------
Prediction Home team Prediction Home Score
Liverpool 5
Arsenal 2
And this is table 2 (Result table)
Col A Col B
----------------------------------------
Actual Home team Actual Home Score
Liverpool 5
Arsenal 1
I would like to compare the 2 columns b so if both same score then 5 points or 0 points if not matched.

The SQL part is this, as for the C# part we will need more details
CREATE TABLE prediction
(
prediction_home_team VARCHAR(100),
prediction_home_score INT
);
CREATE TABLE result
(
actual_home_team VARCHAR(100),
actual_home_score INT
);
INSERT INTO prediction (prediction_home_team, prediction_home_score) VALUES ('Liverpool', 5), ('Arsenal', 2);
INSERT INTO result (actual_home_team, actual_home_score) VALUES ('Liverpool', 5), ('Arsenal', 1);
/*
*
* QUERY:
*
*/
SELECT prediction.prediction_home_team Team,
prediction.prediction_home_score PredictedScore,
RESULT.actual_home_score ActualScore,
CASE
WHEN prediction.prediction_home_score = result.actual_home_score THEN 5
ELSE 0
END Points
FROM prediction
JOIN result ON result.actual_home_team = prediction_home_team

Related

SQL Server : check not existing number into a table

I have a Clients table already populated by thousands of records and now I need to search for a non-existing number in the card number column starting from the number x.
Example: I would like to search for the first available card number starting from number 2000.
Unfortunately I cannot select MAX() as there are records with 9999999 (which is the limit).
Is it possible to do this search through a single SELECT?
It's possible with a few nested SELECTs:
SELECT MIN(`card_number`) + 1 as next_available_number
FROM( SELECT (2000-1) as `card_number`
UNION
SELECT `card_number`
FROM clients
WHERE `card_number` >= 2000
) tmp
WHERE NOT EXISTS ( SELECT NULL
FROM clients
WHERE `card_number` = tmp.`card_number` + 1 )
It can be done with a self-join on your clients table, where you search for the lowest cardnumber for which the cardnumber + 1 does not exist.
In case x is 12, the query would be:
SELECT MIN(cardnumber) + 1
FROM clients
WHERE cardnumber + 1 NOT IN (SELECT cardnumber FROM clients)
AND cardnumber + 1 > 12
Eg. with a dataset of
INSERT INTO clients (cardnumber) VALUES
(1),(2),(3),(4),(5),(6),(7),(8),(9),(11),(12),(13),(14),(15),(17),(18)
this returns 16, but not 10.
Example on SQL Fiddle.
I think this is very similar to this question, but the minimum criteria is new.
If the credit card is represented as integer in your table and your starting number is 2000 you could do something like:
SELECT top 1 (card_id + 1)
FROM CreditCards t
WHERE card_id IN (
SELECT card_id
FROM CreditCards
WHERE card_id LIKE '%[2][0][0][0]%'
)
AND NOT EXISTS (SELECT 1 FROM CreditCards t2 WHERE t2.card_id = t.card_id + 1)
ORDER BY card_id
Example data (Table: CreditCards):
card_id
2000002
2000103
2000000
2000108
2000106
3000201
1000101
Result is: 2000001
Note that %[2][0][0][0]% is fixed here. You could also introduce a parameter.
It is not an optimal solution, but it does the trick.

Multiple IN Clauses in SQL

I'm not sure about the functionality of the IN clause so I want to know if I can run a query safely. For what I understand when using IN clause in SQL Server creates a series of OR statements:
So for example
SELECT * FROM table WHERE column IN (1, 2, 3, 4, 5, 6)
Will be the same that:
SELECT * FROM table WHERE column = 1 OR column = 2 OR column = 3 OR column = 4 OR column = 5 OR column = 6
But what happens when something like this is executed:
SELECT * FROM table WHERE column IN (1, 2, 3) and column2 IN (4,5,6) and column 3 IN (5,7,8)
Here I want to know if for example, if some value from the first IN has two occurrences within the second one it will retrieve both results, or if it's executed in order like 1 and 4 and 5 (The first value within the IN clauses)
I want to run a query with 8 parameters that I need to check in the DB (Sending by C#) but I don't want to build a super huge query with a lot of OR like this (because it will be +90k records)
SELECT * FROM table WHERE (column = 1 and column2 = 4 and column3 = 5 ) or
(column = 2 and column2= 5 and column3 = 7) OR ....
Or I don't know if there is a better approach to solve this, I'm open to ideas.
Thanks
The INs are separate conditions, so the logic is equivalent to:
where (column1 = 1 or column1 = 2 or column1 = 3) and
(column2 = 4 or column2 = 5 or column2 = 6)
Note that this is a logical equivalence. Some databases optimize IN with constant lists, for instance, by creating a binary tree for searching the values. I don't think that SQL Server does such an optimization though.
If you want "alignment", some databases -- but not SQL Server -- support tuples using IN:
where (column1, column2) in ( (1, 4), (2, 5), (3, 5) )
And this can always be represented as:
where (column1 = 1 and column2 = 4) or
(column1 = 2 and column2 = 5) or
(column1 = 3 and column2 = 6)

select max value from oracle table in c#

I have an OracleCommand to select maximum value of type NUMBER from oracle table in a C# application using OracleConnection. when code is excuted I get the value with M letter at the end! so if we suppose max value is 2544, then I get 2544M as maximum value.
here is the code:
OracleCommand command = new OracleCommand("SELECT GREATEST(TA_Counts) FROM Test3.Trn_Sfd", Con2);
Con2.Open();
var returvalue = command.ExecuteScalar();
why value is not return as 2544 int value?!
Because the value is a decimal. This happens due to the type of your column in table. You could verify this looking at this table. If your data type is either integer or float the .net type returned by the reader is decimal.
Greatest doesn't give you the max value of your table:
SQL> with t as (
2 select 1 id, 2 value from dual union all
3 select 2 id, 4 value from dual
4 )
5 select GREATEST(id)
6 from t
7 /
GREATEST(ID)
------------
1
2
The GREATEST function gives you the max value among several values, like:
SQL> ed
Wrote file afiedt.buf
1 with t as (
2 select 1 id, 2 value from dual union all
3 select 2 id, 4 value from dual
4 )
5 select GREATEST(id, value)
6* from t
SQL> /
GREATEST(ID,VALUE)
------------------
2
4
You have to use the max function:
SQL> ED
Wrote file afiedt.buf
1 with t as (
2 select 1 id, 2 value from dual union all
3 select 2 id, 4 value from dual
4 )
5 select max(id)
6* from t
SQL> /
MAX(ID)
----------
2
you might need to use implicit conversion:
(int)command.ExecuteScalar()
use the type you need

SQL Show records that meet a provided criteria

I have the following table
CamId RegNumber DateSeen
5 G1234B 18/02/2014 11:54
3 G1234B 18/02/2014 11:51
5 G11854 18/02/2014 11:50
3 G11854 18/02/2014 11:49
3 G24581 18/02/2014 11:48
5 G24581 18/02/2014 11:47
I would like to retrieve all records with CamId 3 that do not have a later entry in CamId 5 based on the dateseen entry on CamId 3 for that particular reg number.
From the sampe data table above the system should return just one number plate G24581 as it has no later entries in CamId 5.
One method you can employ is to join onto the table twice so that in one table you have the values where CamID is 3 and the other is 5. Then you would want to get all records from the first table that do no have a record in the second table.
Select A.* from Table A
LEFT JOIN ( Select * from Table ) B on A.RegNumber = B.RegNumber AND A.CamID = 3 and B.CamID = 5 AND A.DateSeen <= B.DateSeen
WHERE B.CamID IS NULL
Try this:
var query = from r1 in db.Regs
where r1.CamId == 3 &&
!db.Regs.Any(r2 => r2.CamId==5 && r2.DateSeen>r1.DateSeen && r2.RegNumber==r1.RegNumber)
select r1;

Create SQLite Database From Other SQLite Database C#

I have an SQLite database which a set of tables. All data in these tables can be isolated into a groups of sets by some id. For example:
Table A
ID value1 value2
1 asd fgh
2 sdf ghj
Table B
ID ID2 value4
1 10 vbn
2 11 bnm
Table C
ID2 value5 value6
10 asdfg qwer
11 tyui hjkl
Where each ID column will map the other ID and each ID2 will map to the other ID2.
I want to take this database, and generate a series of smaller databases, each of which have the same structure, but will only contain data from 1 ID:
Database1.sqlite
Table A
ID value1 value2
1 asd fgh
Table B
ID ID2 value4
1 10 vbn
Table C
ID2 value5 value6
10 asdfg qwer
Database2.sqlite
Table A
ID value1 value2
2 sdf ghj
Table B
ID ID2 value4
2 11 bnm
Table C
ID2 value5 value6
11 tyui hjkl
I could just create the tables one by one, gather all data per ID through a series of SELECT statements, then add it through a series of INSERT statements, but I think there has to be a better way.
My other idea is that I can create a series of views, each of which isolates the data into the format above. From there, I could just write these series of views an sqlite file as a database.
My question is how realistic is my view generation idea? Would it be possible to generate a series of views that mimic each table's structure, but for say where ID = 1 and then save those views as an sqlite file? All of this will need to be done in C#. Is there a better way to do what I am trying to do?
Some More Info
These tables can have multiple rows with the same IDs. There will also need to be some primary key / foreign keys for each table. Ideally, we could then take these smaller tables, and then compress them all into a larger table in the future.
It is possible to combine INSERT and SELECT.
Together with ATTACHed databases, this allows to do the copying with one statement per table:
ATTACH 'C:\some\where\Database1.sqlite' AS db1;
CREATE TABLE db1.A(ID, value1, value2);
CREATE TABLE db1.B(ID, ID2, value4);
CREATE TABLE db1.C(ID2, value5, value6);
INSERT INTO db1.A SELECT * FROM main.A WHERE ID = 1;
INSERT INTO db1.B SELECT * FROM main.B WHERE ID = 1;
INSERT INTO db1.C SELECT * FROM main.C
WHERE ID2 IN (SELECT ID2 FROM B WHERE ID = 1);
ATTACH 'C:\some\where\Database2.sqlite' AS db2;
CREATE TABLE db2.A(ID, value1, value2);
CREATE TABLE db2.B(ID, ID2, value4);
CREATE TABLE db2.C(ID2, value5, value6);
INSERT INTO db2.A SELECT * FROM main.A WHERE ID = 2;
INSERT INTO db2.B SELECT * FROM main.B WHERE ID = 2;
INSERT INTO db2.C SELECT * FROM main.C
WHERE ID2 IN (SELECT ID2 FROM B WHERE ID = 2);

Categories