I'm trying to retrieve some columns value from a google cloud sql database, and I want to rename the output column as follows:
select id as tot from mytable
the query result I get is this:
id
value1
value2
value3
...
as you can see the column name is not changed as I wanted.. I also tried
select id as 'tot' from mytable
and (in fact this works, but obviously every row value is set to 'id' instead of the real row value)
select 'id' as 'tot' from mytable
the table schema I'm testing on is as simple as possible:
create table mytable(id varchar(10))
Has anyone encountered this problem before? Am I missing something or doing something wrong?
Thanks in advance for any help, best regards
This works as expected using the command line tool and looks like a bug in the web ui.
Here's what I got from the command line tool use (google_sql.sh)
sql> insert into mytable values('1'), ('2'), ('3');
3 row(s) affected.
sql> select * from mytable;
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
+----+
3 rows in set (0.10 sec)
sql> select id as 'tot' from mytable
-> ;
+-----+
| tot |
+-----+
| 1 |
| 2 |
| 3 |
+-----+
3 rows in set (0.09 sec)
sql> select 'id' as 'tot' from mytable
-> ;
+-----+
| tot |
+-----+
| id |
| id |
| id |
+-----+
3 rows in set (0.09 sec)
I just logged a bug for this: https://code.google.com/p/googlecloudsql/issues/detail?id=60
Related
I have a temporary table that has columns id and value:
| id | value |
And I have a table that aggregates data with columns g_id and value:
| g_id | value |
The id in the temporary table is locally ordered by id, here's 2 examples:
temp_table 1
| id | value |
+----+--------+
| 1 | first |
| 2 | second |
| 3 | third |
temp_table 2
| id | value |
+----+-------+
| 2 | alpha |
| 3 | beta |
| 4 | gamma |
I want to insert all the rows from the temp table into the global table, while having the g_id ordered globally. If I insert temp table 1 before temp table 2, it should be like this:
global_table
| group_id | value |
+----------+--------+
| 1 | first |
| 2 | second |
| 3 | third |
| 4 | alpha |
| 5 | beta |
| 6 | gamma |
For my purposes, it is ok if there are jumps between consecutive numbers, and if 2 inserts are done at the same time, it can be interleaved. The requirement is basically that the id columns are always increasing.
e.g.
Let's say I have 2 sets of queries run at the same time, and the group_id in global_table is auto incremented:
Query 1:
INSERT INTO global_table (value) VALUES (first)
INSERT INTO global_table (value) VALUES (second)
INSERT INTO global_table (value) VALUES (third)
Query 2:
INSERT INTO global_table (value) VALUES (alpha)
INSERT INTO global_table (value) VALUES (beta)
INSERT INTO global_table (value) VALUES (gamma)
I can get something like this:
global_table
| group_id | value |
+----------+--------+
| 1 | first |
| 3 | alpha |
| 4 | second |
| 5 | third |
| 6 | beta |
| 7 | gamma |
How do I achieve something like this with inserting from a table? Like with
INSERT INTO global_table (value)
SELECT t.value
FROM temp_table t
Unfortunately, this may not result in a incrementing id all the time.
The requirement is basically that the id columns are always
increasing.
If I understood you correctly, you should use ORDER BY in your INSERT statement.
INSERT INTO global_table (value)
SELECT t.value
FROM temp_table t
ORDER BY t.id;
In SQL Server, if you include ORDER BY t.id, it will guarantee that the new IDs generated in the global_table table will be in the specified order.
I don't know about other databases, but SQL Server IDENTITY has such guarantee.
Using your sample data, it is guaranteed that the group_id generated for value second will be greater than the value generated for the value first. And group_id for value third will be greater than for value second.
They may be not consecutive, but if you specify ORDER BY, their relative order will be preserved.
Same for the second table, and even if you run two INSERT statements at the same time. Generated group_ids may interleave between two tables, but relative order within each statement will be guaranteed.
See my answer for a similar question with more technical details and references.
I am running the below impala query and i am getting strange results. Why does the 2th query below returns zero results and how to overcome this. I am doing several data pipelines with multiple tables, so i have to use the "with" in the beginning.
1. Query: select * from test where name <> 'INSERT'
+----+--------+
| id | name |
+----+--------+
| 2 | DELETE |
| 2 | HELLO |
+----+--------+
Fetched 2 row(s) in 0.13s
2. Query: with temp as (select * from test where name <> 'INSERT') select * from temp
Modified 0 row(s) in 0.23s
3. Query: with temp as (select * from test where name <> 'HELLO') select * from temp
+----+--------+
| id | name |
+----+--------+
| 2 | DELETE |
| 1 | INSERT |
+----+--------+
Fetched 2 row(s) in 0.12s
It should give the record names with 'HELLO' and 'DELETE' for the 2nd query. but its giving no results. Also noticed the output says "modified", so i am guessing its trying to execute it as DML.
Note : Using Impala Shell v2.11.0-cdh5.14.2
The same query works fine in hive.
It seems to work on my side
with temp as (SELECT *
FROM
(SELECT 'DELETE' AS name
UNION SELECT 'HELLO' AS name
UNION SELECT 'INSERT' AS name) AS subq
WHERE name <> 'INSERT')
select * from temp;
+---------+
| name |
+---------+
| HELLO |
| DELETE |
+---------+
2 rows selected (0.118 seconds)
Could you post the EXPLAIN PLAN of your second query?
I have a table in PostgreSQL with a timestamp column, and I want to modify the table to have a second timestamp column and seed it with the value of the immediately successive timestamp. Is there a way to do this? The tables are fairly large, so a correlated subquery might kill the machine.
More concretely, I want to go from this to that:
+----+------+ +----+------+------+
| ts | data | | ts | te | data |
+----+------+ +----+------+------+
| T | ... | --> | T | U | ... |
| U | ... | | U | V | ... |
| V | ... | | V | null | ... |
+----+------+ +----+------+------+
Basically, I want to be able to hand point in time queries much better (i.e., give me the data for time X).
Basically I think you could just retrieve the timestamp at the query time, not storing it in the table, but if you're performing such action and think that this is what you need then:
You need to add that column to your table:
ALTER TABLE tablename ADD COLUMN te timestamp;
Then perform an update feeding the value with the use of LEAD window function.
UPDATE tablename t
SET te = x.te
FROM (
SELECT ts, lead(ts, 1) OVER (order by ts) AS te
FROM tablename t2
) x
WHERE t.ts = x.ts
Here's an example of how it works using sample integer data: SQL Fiddle.
It will perform exactly the same for timestamp data type values.
select ts,LEAD(ts) over(order by (select null)) as te,data from table_name
I'm new to using stored procedures, what is the best way to update and insert using stored procedures. I have two tables and I can match them by a distinct ID, I want to update if the ID exists in both my load table and my destination table, and I want to insert if the item does not exist in my destination table. Just an example template would be very helpful, thanks!
If I understood well, you want to select values in one table and insert them in other table. If the id exists in the second table, you need to update the row. If I'm not wrong you need something like this:
mysql> select * from table_1;
+----+-----------+-----------+
| id | name | last_name |
+----+-----------+-----------+
| 1 | fagace | acero |
| 2 | ratangelo | saleh |
| 3 | hectorino | josefino |
+----+-----------+-----------+
3 rows in set (0.00 sec)
mysql> select * from table_2;
+----+-----------+-----------+
| id | name | last_name |
+----+-----------+-----------+
| 1 | fagace | acero |
| 2 | ratangelo | saleh |
+----+-----------+-----------+
2 rows in set (0.00 sec)
mysql> insert into table_2 select t1.id,t1.name,t1.last_name from table_1 t1 on duplicate key update name=t1.name, last_name=t1.last_name;
Query OK, 1 row affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> select * from table_2;
+----+-----------+-----------+
| id | name | last_name |
+----+-----------+-----------+
| 1 | fagace | acero |
| 2 | ratangelo | saleh |
| 3 | hectorino | josefino |
+----+-----------+-----------+
3 rows in set (0.00 sec)
mysql>
You should look up the SQL MERGE statement.
It allows you to perform UPSERT's - i.e. INSERT if a key value does not already exist, UPDATE if the key does exist.
http://technet.microsoft.com/en-us/library/bb510625.aspx
However, your requirement to check for a key value in 2 places before you perform an update does make it more complex. I haven't tried this but I would think a VIEW or a CTE could be used to establish if the ID exists in both your tables & then base the MERGE on the CTE/VIEW.
But definitely start by looking at MERGE!
could anyone tell me how to select particular column if i dont know the schema of table .Like if i want only the values in the second column of database table without knowing the column name. Is there a way to do that?
You should almost NEVER rely on column number in a table in any of your code (even though you CAN theoretically do so technically for certain database libraries in certain languages).
There are many reasons, one of the most important is that someone can always ALTER the table and insert a column in the beginning / middle, breaking your code completely.
A second reason is that column positions - even if you assume that the table never changes - make for absolutely UNREADABLE and therefore impossible to maintain code. Will you remember that column 13 was "last_name_3" 2 years from now?
Although I'd never recommend doing what you propose, assuming your RDBMS has implemented the SQL-92 INFORMATION_SCHEMA standard, you could get the column name and use it to build dynamic SQL.
SELECT c.COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS c
WHERE c.TABLE_NAME = 'YourTable'
AND c.ORDINAL_POSITION = 2
Not sure what you wanted to do. And I sincerely expect you don't do what you're doing. But if you jsut wanted to know how to play with technicality. Here is an example to do it. There may be better ways.
mysql> desc test;
+-------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | varchar(100) | YES | | NULL | |
+-------+--------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
mysql> select * from test;
+------+-------+
| id | name |
+------+-------+
| 1 | name1 |
| 2 | name2 |
| 3 | name3 |
| 4 | name4 |
+------+-------+
4 rows in set (0.00 sec)
mysql> select #colid:=column_name from information_schema.columns where table_schema='test' and table_name='test' and ordinal_position=2;
+---------------------+
| #colid:=column_name |
+---------------------+
| name |
+---------------------+
1 row in set (0.01 sec)
mysql> set #sqlstr:=concat('select ', #colid, ' from test');
Query OK, 0 rows affected (0.00 sec)
mysql> prepare sttmt from #sqlstr;
Query OK, 0 rows affected (0.00 sec)
Statement prepared
mysql> execute sttmt;
+-------+
| name |
+-------+
| name1 |
| name2 |
| name3 |
| name4 |
+-------+
4 rows in set (0.00 sec)
refer the last example here http://dev.mysql.com/doc/refman/5.0/en/user-variables.html
By the way, Google gives first link as perfect solution. Select statement with column number instead of column names
Can you do a select * from mytable to figure out what the column names are?
You could also try select * from information_schema.columns where table_name = 'mytable' if your database supports an information_schema view. There are other ways to figure out the names of columns. I would suggest just trying to figure out the name over any other possible workaround.
This could be done with SQL Server/.NET like this:
SqlCommand command =
new SqlCommand("SELECT * FROM TABLE", connection);
connection.Open();
SqlDataReader reader = command.ExecuteReader();
// Call Read before accessing data.
while (reader.Read())
{
string secondVal = reader[1].ToString();
}
I would take a hard look at why you need to do this in the first place though. Seems fishy to me...