Can I hard code a value into column in the SELECT clause - sql

I want to populate column SURVEY_TYPE_ID with 1
Can I do this like so?
SELECT
SURVEY_ID,
SKILL_ID,
1 AS SURVEY_TYPE_ID,
From Table A

This should work as it is:
SELECT
SURVEY_ID,
SKILL_ID,
1 AS SURVEY_TYPE_ID
From Table A
Also, if you want to populate string in the column value just add quotes.
SELECT
SURVEY_ID,
SKILL_ID,
'id_123' AS SURVEY_TYPE_ID
From Table A

This query returns a result set with a third column whose value is 1:
SELECT SURVEY_ID, SKILL_ID, 1 AS SURVEY_TYPE_ID
FROM Table_A
(This is the same as your query with the spurious comma removed.)
If you want to change the value of the column in the table, then you need UPDATE:
UPDATE Table_A
SET SURVEY_TYPE_ID = 1;
If you want to add a new column to the table, then the syntax varies depending on the database, but generally something like this:
ALTER Table_A ADD COLUMN SURVEY_TYPE_ID INT DEFAULT 1;

Related

Dynamic column alias from another column value in SELECT

I was wondering if there a way, in a SELECT statement on Postgres, to alias a column with the value of another column in the same data set.
Given this table:
id
key
value
1
a
d
2
a
e
3
b
f
This would be the result:
id
a
b
1
d
NULL
2
e
NULL
3
NULL
f
Where for each instance the name of the column is determined from the value of key while the value is the value of the column value, not knowing what kind of values will be provided by the column key.
This is a possible (not working) query:
SELECT "id", "value" AS "t"."key" FROM testTable as t;
One way to achieve pivot in Postgres is using CASE :
select id,
max(case when (key='a') then value else NULL end) as a,
max(case when (key='b') then value else NULL end) as b
FROM TestTable
group by id
order by id;
It seems that there is no way to create the column alias dynamically without knowing the values since the beginning. As many commented the only way to achieve this kind of "table re-mapping" is to use the crosstab function.
Crosstab function summary
This function takes 2 arguments:
The first one is a SQL statement that must return 3 columns:
The first column contains the values identifying each instance and that must be grouped in order to get the final result.
The second column contains the values that are used as categories in the final pivot table: each value will create a separate column.
The third column contains the values used to compile the new columns formed: for each category this column has the value of the instance that had the category value in the original table.
The second argument is not mandatory and is a SQL statement that returns the distinct values the function should use as categories.
Example
In the example above we must pass a query to crosstab that:
Returns as the first column the identifier of each final instance (in this case id)
As second column the values used as categories (all values in key)
As third column the values used to fill the categories (all values in value)
So the final query should be:
select * from crosstab(
'select "id", "key", "value" from testTable order by 1, 2;',
'select distinct "key" from testTable order by 1;'
) as result ("id" int8, "a" text, "b" text);
Since the crosstab function requires a column definition for the final pivot table, there is no way to determine the column alias dynamically.
Dynamically infer column names with client
A possible way to do that, with a PostgreSQL client, is to launch the second query we passed as argument to crosstab in order to retrieve the final columns and then infer the final crosstab query.
As an example, with pseudo-javascript:
const client;
const aliases = client.query(`select distinct "key" from testTable order by 1;`);
const finalTable = client.query(`select * from crosstab(
'select "id", "key", "value" from testTable order by 1, 2;',
'select distinct "key" from testTable order by 1;'
) as result ("id" int8, ${aliases.map(v => v + ' data_type').join(',')});`)
Useful articles
https://learnsql.com/blog/creating-pivot-tables-in-postgresql-using-the-crosstab-function/

SQL: How to update an empty column with pre-defined set of values

I have a table with, let's say, 100 records. The table has two columns. The first column (A) has unique values. The second column (B) has NULL values
For 4 elements from column A I'd like to associate some earlier defined values, and they are unique as well.
I don't care about which value from column B will be associated with the value from column A. I'd like to associate 4 unique values with another 4 unique values. Basically, like I'd cut and paste a block of values from one column to another in excel.
How can I do it without using cursors?
I'd like to use one Update statement for ALL rows instead one Update statement for EVERY row as I do now.
Try this:
UPDATE t
SET ColumnB = BValue
FROM Table t
INNER JOIN
(
SELECT 1 AValue, 'Mouse' BValue UNION
SELECT 2, 'Cat' UNION
SELECT 3, 'Dog' UNION
SELECT 4, 'Wolf'
) PreDefined ON(t.ColumnA = PreDefined.AValue)
Use any number you want in the 'PreDefined' table, as long as they are unique and within the range of values in columnA of your original table.
If you are only trying to fill a table for testing purposes, I guess you could:
A) Use the value from Column A itself (as it is already unique).
B) If they are to be different, use some function on the column A's value to obtain a column B value (something simple, like (ColumnA * 10), and this would give youA)
C) Create a temp table with a "dictionary" setting a B value for each possible A value, and then update the rows desired on your table looking up from values on this dictionary table.
Anyway, if you explain a little further your purpose it will be easier to try suggesting you a solution.
if your animal data is already in a database table, then you can use a single update statement like this:
update target_table t4
set columnb = (
select animal_name
from (select columna, animal_name
from (select rownum rowNumber, animal_name from animal_table) t1
join (select rownum rowNumber, columna from target_table t1 where columnb is null) t2
on t1.rowNumber = t2.rowNumber
) t3
where t4.columna = t3.columna
)
;
this works by selecting a sequence number and animal name from the source table, then selecting a sequence number and columna value from your target table. by joining those records on the sequence number you guarantee you get exactly 1 animal name for each columna value. you can then join those columna-to-animal records to your target table to do an update of columnb.
for more background on updating one table from values in another, you might consider the solutions presented here: Update rows in one table with data from another table based on one column in each being equal. the only difference is that in your example, you do not have any column that matches between your target table and your animal names table, so you need to use the rownum to create an arbitrary 1-to-1 matching of records.
if your unique options are in a text file or spreadsheet, then you can format them into a fixed-width space-padded string and pick the one you want using the rownum index like so:
update table_name
set columnb = trim(substr('mouse cat dog wolf ', rownum*6-6, 6))
where columnb is null;

Insert row over existing row, move rows down

I'm trying to insert a new row in the middle of a sql table and move all other rows first to make space for it.
I've tried
setting id=id+1,
but that gives me an error(obviously) because the row id+1 exists already, so this only works for going in the other direction so id=id-1.
What is the correct solution then?
To do the stuff, you should update you table from the end:
UPDATE `table` SET `id`=`id`+1 WHERE `id`>$value ORDER BY `id` DESC
Where $value is your value
You could try something like this:
UPDATE table_name SET id = id + 1 WHERE id >= your_id_value ORDER BY id DESC;
INSERT INTO table_name(..., id, ...) VALUES(..., your_id_value, ...)

SQL With... Update

Is there any way to do some kind of "WITH...UPDATE" action on SQL?
For example:
WITH changes AS
(...)
UPDATE table
SET id = changes.target
FROM table INNER JOIN changes ON table.id = changes.base
WHERE table.id = changes.base;
Some context information: What I'm trying to do is to generate a base/target list from a table and then use it to change values in another table (changing values equal to base into target)
Thanks!
You can use merge, with the equivalent of your with clause as the using clause, but because you're updating the field you're joining on you need to do a bit more work; this:
merge into t42
using (
select 1 as base, 10 as target
from dual
) changes
on (t42.id = changes.base)
when matched then
update set t42.id = changes.target;
.. gives error:
ORA-38104: Columns referenced in the ON Clause cannot be updated: "T42"."ID"
Of course, it depends a bit what you're doing in the CTE, but as long as you can join to your table withint that to get the rowid you can use that for the on clause instead:
merge into t42
using (
select t42.id as base, t42.id * 10 as target, t42.rowid as r_id
from t42
where id in (1, 2)
) changes
on (t42.rowid = changes.r_id)
when matched then
update set t42.id = changes.target;
If I create my t42 table with an id column and have rows with values 1, 2 and 3, this will update the first two to 10 and 20, and leave the third one alone.
SQL Fiddle demo.
It doesn't have to be rowid, it can be a real column if it uniquely identifies the row; normally that would be an id, which would normally never change (as a primary key), you just can't use it and update it at the same time.

how to update a column for all rows in a table with different values for each row in a table of 100 records

my table contains 100 records and i need to update a column with new values(diff value for each record) for each of the 100 records .How can i do this. the column to update the values is not primary key.
UPDATE tablename
SET columnname = CASE id
WHEN 1 THEN 42
WHEN 2 THEN 666
END
With this query columnname will be updated to 42 for the row with id = 1, and 666 for id = 2
Create a table with an autoicrement id and the columns of the original table.
Then
INSERT INTO new_table (column1, column2,.....) -- refer all columns except autoincrement id
SELECT * FROM old_table
Update the old table by joining with the new, assuming the is a key composite or not that distincts each row
Set Unique constraint on this column.
ALTER TABLE YourTableName
ADD CONSTRAINT uc_ColumnID UNIQUE (ColumnName)
Now, whenever you try to update it with duplicate values, sql server will not allow:)
Also a long run scenario
If you're on SQL Server 2005 or newer (you didn't exactly specify.....), you could easily use a CTE (Common Table Expression) for this - basically, you select your PK value, and a counter counting up from 1, and you set each row's ColumnName column to the value of the counter:
;WITH UpdateData AS
(
SELECT
PKValue,
ROW_NUMBER() OVER(ORDER BY .......) AS 'RowNum'
FROM
dbo.YourTable
)
UPDATE dbo.YourTable
SET ColumnName = u.RowNum
FROM UpdateData u
WHERE dbo.YourTable.PKValue = u.PKValue
With this, you're generating a sequence from 1 through 100 in the RowNum field of the CTE, and you're setting this unique value to your underlying table.
load a DataTable say dt with specific row ID of the table which you wanna update.
then execute
foreach(DataRow rw in dt.Rows)
{
update table_name set column_name=desired_value where specific_column=rw
}