I have a simple load statement:
LOAD FIELDA,
FIELDB,
FIELDC,
FIELDD,
FIELDE
FROM
[C:\Users\XXX\data.QVD]
(qvd);
This loads all the data fine.
If i add an expression into a straight table it gives me the concatenated field:
concat(FIELDA&'.'&FIELDB&'.'&FIELDC&'.'&IF(Isnull(FIELDD), '0', FIELDD)&'.'&IF(Isnull(FIELDE), '0', FIELDE)) as MERGED
This works, however if i try and add a concatenated field from the load statement i get an error:
LOAD FIELDA,
FIELDB,
FIELDC,
FIELDD,
FIELDE,
concat(FIELDA&'.'&FIELDB&'.'&FIELDC&'.'&IF(Isnull(FIELDD), '0', FIELDD)&'.'&IF(Isnull(FIELDE), '0', FIELDE)) as MERGED
FROM
[C:\Users\XXX\data.QVD]
(qvd);
Invalid expression
The concat function is an aggregation function so it wants a group by to know what to do, hence the Invalid expression error. In the front end the dimension you choose for the chart serves that purpose.
If you just want to concat the fields line for line just remove the concat function.
FIELDA&'.'&FIELDB&'.'&FIELDC&'.'&IF(Isnull(FIELDD), '0', FIELDD)&'.'&IF(Isnull(FIELDE), '0', FIELDE) as MERGED
The actual use of the concat function would be something like this, run it and see the difference between MERGE and MERGE2;
A:
LOAD * INLINE [
FieldA, FieldB,FieldC
1, 2,1
1, 0,1
2, 9,1
2, 4,1
];
B:
load FieldA,
concat(FieldB,'|') as MERGE
Resident A
group by FieldA;
C:
load FieldA,
FieldB,
FieldC,
FieldA&'.'&FieldB&'.'&FieldC as MERGE2
resident A;
drop table A;
Related
I'm trying to work out why my union queries are giving me type conversion errors
I am trying to create a report that has to be formatted in a way that multiple union queries seems like the easiest option.
Essentially I want an output that shows the key column, and then a row for each other column, and the value for that column, so it would kind of look like this:
Key1 Column1 Value
Key1 Column2 Value
Key2 Column1 Value
Key2 Column2 Value
I'm doing this for about 40 columns though, so its a lot of select statements.
All of my select statements are structured the same:
SELECT tb1.Key AS 'Key', 'Column1' AS 'Column', tb1.Column1 AS 'Value'
union
SELECT tb1.Key AS 'Key', 'Column2' AS 'Column', tb1.Column2 AS 'Value'
etc
When running all of the queries individually I have no issue, but when I try to run all, of them I get an issue converting various strings to type int.
In order to try rectifying this I've tried casting every 'value' column as NVARCHAR and I still get an error that some of the strings are trying to be converted to type int, but I'm not sure why that is.
Generally when doing a UNION, the data types of the columns of your result set will be determined by the first query that executes or returns rows. So, if you're not sure which queries in the UNIONs return data you should CAST all your columns explicitly. Something like:
SELECT
CAST(tb1.Key AS INTEGER) AS 'Key',
CAST('Column1' AS VARCHAR(100)) AS 'Column',
CAST(tb1.Column1 AS VARCHAR(100)) AS 'Value'
FROM MyTableA AS tb1
UNION
SELECT
CAST(tb1.Key AS INTEGER) AS 'Key',
CAST('Column1' AS VARCHAR(100)) AS 'Column',
CAST(tb1.Column1 AS VARCHAR(100)) AS 'Value'
FROM MyTableB AS tb1
If your UNIONs are simple SELECTs from the same table, it shouldn't be a problem. But the issue may come up when some rows return NULL values and data types may not be what you expect.
The problem is that the columns for a union need to be of the same type. Typically, you can store values as strings.
More importantly, you don't need union for this. SQL Server supports lateral joins using the apply keyword. This is simpler to express as:
select tb1.key, v.column, v.value
from tb1 cross apply
(values ('Column1', convert(nvarchar(max), tb1.Column1),
('Column2', convert(nvarchar(max), tb1.Column2),
. . .
) v(column, value);
here is what I'm trying to do- I have a table with lots of columns and want to create a view with one of the column reassigned based on certain combination of values in other columns, e.g.
Name, Age, Band, Alive ,,, <too many other fields)
And i want a query that will reassign one of the fields, e.g.
Select *, Age =
CASE When "Name" = 'BRYAN ADAMS' AND "Alive" = 1 THEN 18
ELSE "Age"
END
FROM Table
However, the schema that I now have is Name, Age, Band, Alive,,,,<too many>,, Age
I could use 'AS' in my select statment to make it
Name, Age, Band, Alive,,,,<too many>,, Age_Computed.
However, I want to reach the original schema of
Name, Age, Band, Alive.,,,, where Age is actually the computed age.
Is there a selective rename where I can do SELECT * and A_1 as A, B_1 as b? (and then A_1 completely disappears)
or a selective * where I can select all but certain columns? (which would also solve the question asked in the previous statement)
I know the hacky way where I enumerate all columns and create an appropriate query, but I'm still hopeful there is a 'simpler' way to do this.
Sorry, no, there is not a way to replace an existing column name using a SELECT * construct as you desire.
It is always better to define columns explicitly, especially for views, and never use SELECT *. Just use the table's DDL as a model when you create the view. That way you can alter any column definition you want (as in your question) and eliminate columns inappropriate for the view. We use this technique to mask or eliminate columns containing sensitive data like social security numbers and passwords. The link provided by marc_s in the comments is a good read.
Google BigQuery supports SELECT * REPLACE:
A SELECT * REPLACE statement specifies one or more expression AS identifier clauses. Each identifier must match a column name from the SELECT * statement.
In the output column list, the column that matches the identifier in a REPLACE clause is replaced by the expression in that REPLACE clause.
A SELECT * REPLACE statement does not change the names or order of columns. However, it can change the value and the value type.
Select *, Age = CASE When "Name" = 'BRYAN ADAMS' AND "Alive" = 1 THEN 18
ELSE "Age"
END
FROM tab
=>
SELECT * REPLACE(CASE WHEN Name = 'BRYAN ADAMS' AND Alive = 1 THEN 18
ELSE Age END AS Age)
FROM Tab
Actually, there is a way to do this in MySQL. You need to use a hack to select all but one column as posted here, then add it separately in the AS statement.
Here is an example:
-- Set-up some example data
DROP TABLE IF EXISTS test;
CREATE TABLE `test` (`ID` int(2), `date` datetime, `val0` varchar(1), val1 INT(1), val2 INT(4), PRIMARY KEY(ID, `date`));
INSERT INTO `test` (`ID`, `date`, `val0`, `val1`, `val2`) VALUES
(1, '2016-03-07 12:20:00', 'a', 1, 1001),
(1, '2016-04-02 12:20:00', 'b', 2, 1004),
(1, '2016-03-01 10:09:00', 'c', 3, 1009),
(1, '2015-04-12 10:09:00', 'd', 4, 1016),
(1, '2016-03-03 12:20:00', 'e', 5, 1025);
-- Select all columns, renaming 'val0' as 'yabadabadoo':
SET #s = CONCAT('SELECT ', (SELECT REPLACE(GROUP_CONCAT(COLUMN_NAME), 'val0,', '')
FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'test' AND TABLE_SCHEMA =
'<database_name>'), ', val0 AS `yabadabadoo` FROM test');
PREPARE stmt1 FROM #s;
EXECUTE stmt1;
I have a tabular form in which I need to generate a dynamic amount of select lists based on the number of values in COL1 that are relevant to the query.
APEX_ITEM.SELECT_LIST_FROM_QUERY_XL(5, COL1, 'query...',p_show_null=>'NO') "COL1"
This works fine when the query returns at least one row. It creates x amount of select lists where x is the number of rows returned by the query. However, when no rows are returned, no select lists are created. How can I make it generate one select list when the query returns no results?
You could do something like this:
select ...,
APEX_ITEM.SELECT_LIST_FROM_QUERY_XL(5, COL1, 'query...',p_show_null=>'NO') "COL1"
from ...
where ...
union all
select ...,
APEX_ITEM.SELECT_LIST_FROM_QUERY_XL(5, 'xxx', 'query...',p_show_null=>'NO') "COL1"
from dual
where not exists (select null from <first query>)
I am newbie to the SQL.
I have a requirement where users might select any values from any of the 3 'multiple list' dropdown box. There might be cases where user can completely ignore any of the dropdown box out of the 3.
So i need a query which can handle that.
The equivalent select query with values looks like this.
SELECT * FROM TABLE WHERE
description1 LIKE '%SHK ABS%' OR
description2 LIKE '%SHK ABS%' OR
description3 LIKE '%SHK ABS%' OR
description4 LIKE '%SHK ABS%' and
**Year** in ('2017','2016') and
**Program** in ('CDPGM');
Problem:
I tried a lot but not able to write a query which accepts empty values in 'IN' clause.
Example: If user dint select any year and program, then empty values will be passed. Basically the query should act like it will ignore that columns in where clause.
Any idea how to achieve this ?
From what you posted I'm guessing you have a problem defining the blank value.
SELECT * FROM table
WHERE col_name IS NULL OR
col_name IN (<list_of_your_values>, '', 0,)
As per I understand there can be three type of empty values according to your case: NULL, Blank and Space(s).
The in clause to match those will look like:
SELECT * FROM table_name WHRE col_name in (null, '', <your other values>);
I have tested it in MySQL 5.6(latest version). For other versions/DBMSs you may need to use trim function:
SELECT * FROM table_name WHRE trim(col_name) in (null, '', <your other values>);
Edit:
For integer type column the empty valuea will be NULL only, OR you can also treat 0 as empty value:
SELECT * FROM table_name WHRE col_name in (null, 0, <your other values>);
here is what I'm trying to do- I have a table with lots of columns and want to create a view with one of the column reassigned based on certain combination of values in other columns, e.g.
Name, Age, Band, Alive ,,, <too many other fields)
And i want a query that will reassign one of the fields, e.g.
Select *, Age =
CASE When "Name" = 'BRYAN ADAMS' AND "Alive" = 1 THEN 18
ELSE "Age"
END
FROM Table
However, the schema that I now have is Name, Age, Band, Alive,,,,<too many>,, Age
I could use 'AS' in my select statment to make it
Name, Age, Band, Alive,,,,<too many>,, Age_Computed.
However, I want to reach the original schema of
Name, Age, Band, Alive.,,,, where Age is actually the computed age.
Is there a selective rename where I can do SELECT * and A_1 as A, B_1 as b? (and then A_1 completely disappears)
or a selective * where I can select all but certain columns? (which would also solve the question asked in the previous statement)
I know the hacky way where I enumerate all columns and create an appropriate query, but I'm still hopeful there is a 'simpler' way to do this.
Sorry, no, there is not a way to replace an existing column name using a SELECT * construct as you desire.
It is always better to define columns explicitly, especially for views, and never use SELECT *. Just use the table's DDL as a model when you create the view. That way you can alter any column definition you want (as in your question) and eliminate columns inappropriate for the view. We use this technique to mask or eliminate columns containing sensitive data like social security numbers and passwords. The link provided by marc_s in the comments is a good read.
Google BigQuery supports SELECT * REPLACE:
A SELECT * REPLACE statement specifies one or more expression AS identifier clauses. Each identifier must match a column name from the SELECT * statement.
In the output column list, the column that matches the identifier in a REPLACE clause is replaced by the expression in that REPLACE clause.
A SELECT * REPLACE statement does not change the names or order of columns. However, it can change the value and the value type.
Select *, Age = CASE When "Name" = 'BRYAN ADAMS' AND "Alive" = 1 THEN 18
ELSE "Age"
END
FROM tab
=>
SELECT * REPLACE(CASE WHEN Name = 'BRYAN ADAMS' AND Alive = 1 THEN 18
ELSE Age END AS Age)
FROM Tab
Actually, there is a way to do this in MySQL. You need to use a hack to select all but one column as posted here, then add it separately in the AS statement.
Here is an example:
-- Set-up some example data
DROP TABLE IF EXISTS test;
CREATE TABLE `test` (`ID` int(2), `date` datetime, `val0` varchar(1), val1 INT(1), val2 INT(4), PRIMARY KEY(ID, `date`));
INSERT INTO `test` (`ID`, `date`, `val0`, `val1`, `val2`) VALUES
(1, '2016-03-07 12:20:00', 'a', 1, 1001),
(1, '2016-04-02 12:20:00', 'b', 2, 1004),
(1, '2016-03-01 10:09:00', 'c', 3, 1009),
(1, '2015-04-12 10:09:00', 'd', 4, 1016),
(1, '2016-03-03 12:20:00', 'e', 5, 1025);
-- Select all columns, renaming 'val0' as 'yabadabadoo':
SET #s = CONCAT('SELECT ', (SELECT REPLACE(GROUP_CONCAT(COLUMN_NAME), 'val0,', '')
FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'test' AND TABLE_SCHEMA =
'<database_name>'), ', val0 AS `yabadabadoo` FROM test');
PREPARE stmt1 FROM #s;
EXECUTE stmt1;