SQL: Select attribute from row given primary key - sql

New to SQL, I need to be able to retrieve an attribute from a row given a primary key. Take this table, for example:
Lets say I'm given the CustomerID 3. What would the SQL query be if I wanted to retrieve the Country associated with that ID?
(table is from https://www.w3schools.com/sql/sql_distinct.asp)

select country from my_table where customerID in(3);

Simply:
SELECT Country FROM YourTable WHERE CustomerID = 3;

Related

Update value using row index

Say I have a table like below with values I want to update in specific rows, but no primary key, I only know the index of the row I want to update. Is this possible with generic SQL or would I need some DB specific tools? I'm using Postgres and SQLite. I realise this is bad DB design and the obvious solution is to simply add an id primary key to the table, but my use case is the DB is the backend for a flexible Excel-like application, where I have no control over the table schema, as it is user defined.
CREATE TABLE fruits (name TEXT);
INSERT INTO fruits VALUES (banana) (aple) (orange);
To fix the typo, I want to do something like:
UPDATE fruits SET name = 'apple' WHERE *row index* = 1;
Note I'm using 0-indexing in this pseudo code example.
Did you try
UPDATE fruits SET name='<new_name>' WHERE rowid=3 ?
rowid docs
You could try
UPDATE fruits SET name = 'apple' WHERE name =(
SELECT name FROM
(SELECT name, row_number() over (order by name) as line_number FROM fruits )
A
WHERE line_number = 1
)
So ROW_NUMBER is dynamically creating a unique number for each name, but it is doing so by sorting the results by name. So the index will be 1 if you want to select the 'Aple' entry.

Looking for SQL request

I have datatable in Microsoft SQL 2012
It is possible to select data values with newest key position with one request?
Or maybe not with one?
Result i want should be 10,20,30,50,70
Try this:
select data from tableName where id in (select MAX(id) from tableName group by key)
You could do it using the following:
SELECT data
FROM datatable
WHERE id IN (
SELECT MAX(ID) latest_id
FROM datatable
GROUP BY key
)
This picks out the latest row for each key (going by incrementing ID). Then you simply only pick these rows using the IN which excludes the non-latest rows.
yes, it is:
select Data from table
where Key = (select max(Key) from table)
order by ID
This will output all Data with highest Key, assuming that highest=newest

find unique rows using SQL?

I want to return all the rows from a table which are unique. I.e. if a certain field in two rows contain the same name, that name shouldn't be shown.
Since you want only the uniques names (and not an unique row for every names like you could have with DISTINCT), you have to use a GROUP BY and a HAVING (instead of a WHERE, because your parameter is the result of a function, not a variable) :
SELECT name FROM myTable GROUP BY name HAVING COUNT(name) = 1
SELECT DISTINCT column_name FROM table
If you want the complete rows, then use row_number() or distinct on:
select distinct on (name) t.*
from table t
order by name;

Logically determine a composite key in SQL

I'm working with an MSSQL table that does not have a primary or unique key contstraint defined. There are two fields, lets call them xId and yId, that I believe together would be a composite key, but I want to confirm this by examining the data.
I'm thinking that I should be able to write a SQL count statement that I can compare to the total number of records on the table that would logically determine if the combination of xId and yId (or a third column id necessary) could in fact act as a composite key. However, I'm having trouble coming up with the right GROUP BY or other type of clause that would confirm or disprove this.
Any ideas?
Use group by and having:
select xid,yid
from table
group by xid,yid
having count(1) > 1
This will show any pairs that are non-unique, so if there are no rows returned its a good key.
Just do a count of the total rows of the table, and then do
select count(1)
from(
select xid,yid
from table
group by xid,yid
)a;
if all pairs of xid and yid form a unique identifier, then the two numbers will be the same.
Alternatively, you could count the number of distinct pairs of xid and yid and find the largest such number:
select max(num_rows)
from(
select xid,yid,count(1) as num_rows
from table
group by xid,yid
)a;
The result of this query is 1 if and only if (xid,yid) pairs form a unique identifier for your table.
this will list all the problem combinations (if any) of xid,yid:
SELECT
COUNT(*),xid,yid
FROM YourTable
GROUP BY xid,yid
HAVING COUNT(*)>1

Underlying rows in Group By

I have a table with a certain number of columns and a primary key column (suppose OriginalKey). I perform a GROUP BY on a certain sub-set of those columns and store them in a temporary table with primary key (suppose GroupKey). At a later stage, I may need to get more details about one or more of those groupings (which can be found in the temporary table) i.e. I need to know which were the rows from the original table that formed that group. Simply put, I need to know the mappings between GroupKey and OriginalKey. What's the best way to do this? Thanks in advance.
Example:
Table Student(
StudentID INT PRIMARY KEY,
Level INT, --Grade/Class/Level depending on which country you are from)
HomeTown TEXT,
Gender CHAR)
INSERT INTO TempTable SELECT HomeTown, Gender, COUNT(*) AS NumStudents FROM Student GROUP BY HomeTown, Gender
On a later date, I would like to find out details about all towns that have more than 50 male students and know details of every one of them.
How about joining the 2 tables using the GroupKey, which, you say, are the same?
Or how about doing:
select * from OriginalTable where
GroupKey in (select GroupKey from my_temp_table)
You'd need to store the fields you grouped on in your temporary table, so you can join back to the original table. e.g. if you grouped on fieldA, fieldB, and fieldC, you'd need something like:
select original.id
from original
inner join temptable on
temptable.fieldA = original.fieldA and
temptable.fieldB = original.fieldB and
temptable.fieldC = original.fieldC