SQL ACCESS how to select and then append column wise - sql

I am wondering how I can query select Value for each ID from source table shown below
and then append column wise to create a table like this
I only know how to select for one ID like this
SELECT DATA1.No,DATA1.Value
FROM DATA1
WHERE DATA1.ID='F'

you better change value field to val (value is reserved word),
and the SQL :
TRANSFORM Sum(DATA1.Value) AS SumOfValue
SELECT DATA1.[NO]
FROM DATA1
GROUP BY DATA1.[NO]
PIVOT DATA1.ID;

Related

Flatten out a Record field

Assume we have a BigQuery table like the following:
Where "Col1" is a Record field. What would be the most efficient way to "flatten out" the table so that part of the Record field becomes columns:
Consider below option
select * from (
select key, name, value
from your_table, unnest(col1)
)
pivot (any_value(value) for name in ('A','B','C','D'))
if applied to sample data as in your question
the output is

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/

t-sql query returns undefined after using ORDER BY

I am currently working with a MS SQL database on Windows 2012 Server
I need to query only 1 column from a table that I only have access to read, not make any kind of changes.
Problem is that the name of the column is "Value"
My code is this:
SELECT 'Value' FROM table
If I add
`ORDER BY 'Value'`
The issue is that the query is returning an empty list of results.
Things I've tried already
I tried replacing ' with `"' but this didn't work either.
I also tried writing SELECT * instead of SELECT VALUE
Using the table name in the SELECT or ORDER clauses again didn't help
You are claiming that this query:
SELECT 'Value'
FROM table
ORDER BY 'Value'
Is returning no rows. That's not quite correct. It is returning an error because SQL Server does not allow constant expressions as keys for ORDER BY (or GROUP BY for that matter).
Do not use single quotes. In this case:
SELECT 'Value' as val
FROM table
ORDER BY val;
Or, if value is a column in the table:
SELECT t.Value
FROM table t
ORDER BY t.Value;
Value is not a reserved word in SQL Server, but if it were, you could escape it:
SELECT t.[Value]
FROM table t
ORDER BY t.[Value];
it looks like your table has null values. and because of the order by all null values come first.
try to add filter like this
select Value FROM table
where Value is not null and Value <> ''
order by Value

SQL statement to return data from a table in an other sight

How would the SQL statement look like to return the bottom result from the upper table?
The last letter from the key should be removed. It stands for the language. EXP column should be split into 5 columns with the language prefix and the right value.
I'm weak at writing more or less difficult SQL statements so any help would be appreciated!
The Microsoft Access equivalent of a PIVOT in SQL Server is known as a CROSSTAB. The following query will work for Microsoft Access 2010.
TRANSFORM First(table1.Exp) AS FirstOfEXP
SELECT Left([KEY],Len([KEY])-2) AS [XKEY]
FROM table1
GROUP BY Left([KEY],Len([KEY])-2)
PIVOT Right([KEY],1);
Access will throw a circular field reference error if you try to name the row heading with KEY since that is also the name of the original table field that you are deriving it from. If you do not want XKEY as the field name, then you would need to break apart the above query into two separate queries as shown below:
qsel_table1:
SELECT Left([KEY],Len([KEY])-2) AS XKEY
, Right([KEY],1) AS [Language]
, Table1.Exp
FROM Table1
ORDER BY Left([KEY],Len([KEY])-2), Right([KEY],1);
qsel_table1_Crosstab:
TRANSFORM First(qsel_table1.Exp) AS FirstOfEXP
SELECT qsel_table1.XKEY AS [KEY]
FROM qsel_table1
GROUP BY qsel_table1.XKEY
PIVOT qsel_table1.Language;
In order to always output all language columns regardless of whether there is a value or not, you need to spike of those values into a separate table. That table will then supply the row and column values for the crosstab and the original table will supply the value expression. Using the two query solution above we would instead need to do the following:
table2:
This is a new table with a BASE_KEY TEXT*255 column and a LANG TEXT*1 column. Together these two columns will define the primary key. Populate this table with the following rows:
"AbstractItemNumberReportController.SelectPositionen", "D"
"AbstractItemNumberReportController.SelectPositionen", "E"
"AbstractItemNumberReportController.SelectPositionen", "F"
"AbstractItemNumberReportController.SelectPositionen", "I"
"AbstractItemNumberReportController.SelectPositionen", "X"
qsel_table1:
This query remains unchanged.
qsel_table1_crosstab:
The new table2 is added to this query with an outer join with the original table1. The outer join will allow all rows to be returned from table2 regardless of whether there is a matching row in the table1. Table2 now supplies the values for the row and column headings.
TRANSFORM First(qsel_table1.Exp) AS FirstOfEXP
SELECT Table2.Base_KEY AS [KEY]
FROM Table2 LEFT JOIN qsel_table1 ON (Table2.BASE_KEY = qsel_table1.XKEY)
AND (Table2.LANG = qsel_table1.Language)
GROUP BY Table2.Base_KEY
PIVOT Table2.LANG;
Try something like this:
select *
from
(
select 'abcd' as [key], right([key], 1) as id, expression
from table1
) x
pivot
(
max(expression)
for id in ([D], [E])
) p
Demo Fiddle

How to select items with all possible id-s or just a particular one using the same query?

Is there a variable in SQL that can be used to represent ALL the possible values of a field? Something like this pseudo-code
SELECT name FROM table WHERE id = *ALL_EXISTING_ID-s*
I want to return all rows in this case, but later when I do a search and need only one item I can simply replace that variable with the id I'm looking for, i.e.
SELECT name FROM table WHERE id = 1
The simplest way is to remove the WHERE clause. This will return all rows.
SELECT name FROM table
If you want some "magic" value you can use for the ID that you can use in your existing query and it will return all rows, I think you're out of luck.
Though you could use something like this:
SELECT name FROM table WHERE id = IFNULL(?, id)
If the value NULL is provided, all rows will be returned.
If you don't like NULL then try the following query, which will return all rows if the value -1 is provided:
SELECT name FROM table WHERE id = IFNULL(NULLIF(?, -1), id)
Another approach that achieves the same effect (but requires binding the id twice) is:
SELECT name FROM table WHERE (id = ? OR ? = -1)