I am looking for a SQL Server query that could transfer source SQL table data:
TextID | Text | LanguageID
-------|-------|-------------------------------------
app.aa | Hi | 6a13ea09-46ea-4c93-9b6a-e26bdc6ff4d8
app.cc | Hund | 0c894bb7-4937-4903-906a-d1b1dd64935c
app.aa | Hallo | 0c894bb7-4937-4903-906a-d1b1dd64935c
app.cc | Dog | 6a13ea09-46ea-4c93-9b6a-e26bdc6ff4d8
app.bb | Star | 6a13ea09-46ea-4c93-9b6a-e26bdc6ff4d8
...
into table like this one:
TextID | Original | Translated
-------|----------|-----------
app.aa | Hi | Hallo
app.bb | Star | -
app.cc | Dog | Hund
...
so that I can use it as a DataSource for GridView in ASP .NET. Thank you in advance for your help.
Whenever you need to combine data from two different rows into one, you need to join. For example:
select src.TextID "TextID", src.Text "Original", tr.Text "Translated"
from source_table src
left join source_table tr
on src.TextID = tr.TextID
and src.LangID = 'xxx' -- xxx is the source language id
and tr.LangID = 'yyy' -- yyy is the target language id
The left join ensures that untranslated words are included with a null translated value. To make a table for your DataSource, you'll need to wrap create table (or maybe create view) around the select:
create table translations as
select ...
Related
Suppose that I have a table named agents_timesheet that having a structure like this:
ID | name | health_check_record | date | clock_in | clock_out
---------------------------------------------------------------------------------------------------------
1 | AAA | {"mental":{"stress":"no", "depression":"no"}, | 6-Dec-2021 | 08:25:07 |
| | "physical":{"other_symptoms":"headache", "flu":"no"}} | | |
---------------------------------------------------------------------------------------------------------
2 | BBB | {"mental":{"stress":"no", "depression":"no"}, | 6-Dec-2021 | 08:26:12 |
| | "physical":{"other_symptoms":"no", "flu":"yes"}} | | |
---------------------------------------------------------------------------------------------------------
3 | CCC | {"mental":{"stress":"no", "depression":"severe"}, | 6-Dec-2021 | 08:27:12 |
| | "physical":{"other_symptoms":"cancer", "flu":"yes"}} | | |
Now I need to get all agents having flu at the day. As for getting the flu from a single JSON in Oracle SQL, I can already get it by this SQL statement:
SELECT * FROM JSON_TABLE(
'{"mental":{"stress":"no", "depression":"no"}, "physical":{"fever":"no", "flu":"yes"}}', '$'
COLUMNS (fever VARCHAR(2) PATH '$.physical.flu')
);
As for getting the values from the column health_check_record, I can get it by utilizing the SELECT statement.
But How to get the values of flu in the JSON in the health_check_record of that table?
Additional question
Based on the table, how can I retrieve full list of other_symptoms, then it will get me this kind of output:
ID | name | other_symptoms
-------------------------------
1 | AAA | headache
2 | BBB | no
3 | CCC | cancer
You can use JSON_EXISTS() function.
SELECT *
FROM agents_timesheet
WHERE JSON_EXISTS(health_check_record, '$.physical.flu == "yes"');
There is also "plain old way" without JSON parsing only treting column like a standard VARCHAR one. This way will not work in 100% of cases, but if you have the data in the same way like you described it might be sufficient.
SELECT *
FROM agents_timesheet
WHERE health_check_record LIKE '%"flu":"yes"%';
How to get the values of flu in the JSON in the health_check_record of that table?
From Oracle 12, to get the values you can use JSON_TABLE with a correlated CROSS JOIN to the table:
SELECT a.id,
a.name,
j.*,
a."DATE",
a.clock_in,
a.clock_out
FROM agents_timesheet a
CROSS JOIN JSON_TABLE(
a.health_check_record,
'$'
COLUMNS (
mental_stress VARCHAR2(3) PATH '$.mental.stress',
mental_depression VARCHAR2(3) PATH '$.mental.depression',
physical_fever VARCHAR2(3) PATH '$.physical.fever',
physical_flu VARCHAR2(3) PATH '$.physical.flu'
)
) j
WHERE physical_flu = 'yes';
db<>fiddle here
You can use "dot notation" to access data from a JSON column. Like this:
select "DATE", id, name
from agents_timesheet t
where t.health_check_record.physical.flu = 'yes'
;
DATE ID NAME
----------- --- ----
06-DEC-2021 2 BBB
Note that this approach requires that you use an alias for the table name (so you can use it in accessing the JSON data).
For testing I used the data posted by MT0 on dbfiddle. I am not a big fan of double-quoted column names; use something else for "DATE", such as dt or date_.
this is my first entry, so please excuse me for any mistakes I might make writing this Post.
I have an oracle database schema full of Table Views. I want to use the "TEXT_VC" column in the "all_views" table to get a list of the source table names.
This is my statement so far:
SELECT view_name, text_vc, REGEXP_SUBSTR(TEXT_VC,'from (.+?) ') AS source_table
FROM all_views
WHERE owner = 'OWNER';
I still have a view problems with this regex.
First of all, I am getting "from table_name" as a result. I don't want to get "from" in my result set.
Secondly, the column TEXT_VC basically displays the SQL behind the view. So in some cases I don't get any results, because there are line breaks. I tried working with \n and \r but I am not able to generate the result I want.
Can anyone please help me?
select * from all_dependencies
Demo
create table mytable_1 (i int);
create table mytable_2 (i int);
create view myview
as
select count(*) as cnt
from mytable_1 t1
join mytable_2 t2
on t2.i = t1.i
;
select *
from all_dependencies
where owner = 'DMARKOVITZ'
and name = 'MYVIEW'
;
+------------+--------+------+------------------+-----------------+-----------------+----------------------+-----------------+
| OWNER | NAME | TYPE | REFERENCED_OWNER | REFERENCED_NAME | REFERENCED_TYPE | REFERENCED_LINK_NAME | DEPENDENCY_TYPE |
+------------+--------+------+------------------+-----------------+-----------------+----------------------+-----------------+
| DMARKOVITZ | MYVIEW | VIEW | DMARKOVITZ | MYTABLE_1 | TABLE | (null) | HARD |
| DMARKOVITZ | MYVIEW | VIEW | DMARKOVITZ | MYTABLE_2 | TABLE | (null) | HARD |
+------------+--------+------+------------------+-----------------+-----------------+----------------------+-----------------+
I'm a bit stumped on a query I need to write for work. I have the following two tables:
|===============Patterns==============|
|type | bucket_id | description |
|-----------------------|-------------|
|pattern a | 1 | Email |
|pattern b | 2 | Phone |
|==========Results============|
|id | buc_1 | buc_2 |
|-----------------------------|
|123 | pass | |
|124 | pass |fail |
In the results table, I can see that entity 124 failed a validation check in buc_2. Looking at the patterns table, I can see bucket 2 belongs to pattern b (bucket_id corresponds to the column name in the results table), so entity 124 failed phone validation. But how do I write a query that joins these two tables on the value of one of the columns? Limitations to how this query is going to be called will most likely prevent me from using any cursors.
Some crude solutions:
SELECT "id", "description" FROM
Results JOIN Patterns
ON "buc_1" = 'fail' AND "bucket_id" = 1
union all
SELECT "id", "description" FROM
Results JOIN Patterns
ON "buc_2" = 'fail' AND "bucket_id" = 2
Or, with a very probably better execution plan:
SELECT "id", "description" FROM
Results JOIN Patterns
ON "buc_1" = 'fail' AND "bucket_id" = 1
OR "buc_2" = 'fail' AND "bucket_id" = 2;
This will report all failure descriptions for each id having a fail case in bucket 1 or 2.
See http://sqlfiddle.com/#!4/a3eae/8 for a live example
That being said, the right solution would be probably to change your schema to something more manageable. Say by using an association table to store each failed test -- as you have in fact here a many to many relationship.
An other approach if you are using Oracle ≥ 11g, would be to use the UNPIVOT operation. This will translate columns to rows at query execution:
select * from Results
unpivot ("result" for "bucket_id" in ("buc_1" as 1, "buc_2" as 2))
join Patterns
using("bucket_id")
where "result" = 'fail';
Unfortunately, you still have to hard-code the various column names.
See http://sqlfiddle.com/#!4/a3eae/17
It looks to me that what you really want to know is the description(in your example Phone) of a Pattern entry given the condition that the bucket failed. Regardless of the specific example you have you want a solution that fulfills that condition, not just your particular example.
I agree with the comment above. Your bucket entries should be tuples(rows) and not arguments, and also you should share the ids on each table so you can actually join them. For example, Consider adding a bucket column and index their number then just add ONE result column to store the state. Like this:
|===============Patterns==============|
|type | bucket_id | description |
|-----------------------|-------------|
|pattern a | 1 | Email |
|pattern b | 2 | Phone |
|==========Results====================|
|entity_id | bucket_id |status |
|-------------------------------------|
|123 | 1 |pass |
|124 | 1 |pass |
|123 | 2 | |
|124 | 2 |fail |
1.-Use an Inner Join: http://www.w3schools.com/sql/sql_join_inner.asp and the WHERE clause to filter only those buckets that failed:
2.-Would this example help?
SELECT Patterns.type, Patterns.description, Results.entity_id,Results.status
INNER JOIN Results
ON
Patterns.bucket_id=Results.bucket_id
WHERE
Results.status=fail
Lastly, I would also add a primary_key column to each table to make sure indexing is faster for each unique combination.
Thanks!
I have a following table (simplified version) in SQLServer.
Table Events
-----------------------------------------------------------
| Room | User | Entered | Exited |
-----------------------------------------------------------
| A | Jim | 2014-10-10T09:00:00 | 2014-10-10T09:10:00 |
| B | Jim | 2014-10-10T09:11:00 | 2014-10-10T09:22:30 |
| A | Jill | 2014-10-10T09:00:00 | NULL |
| C | Jack | 2014-10-10T09:45:00 | 2014-10-10T10:00:00 |
| A | Jack | 2014-10-10T10:01:00 | NULL |
.
.
.
I need to create a query that returns person's whereabouts in given timestamps.
For an example: Where was (Jim at 2014-10-09T09:05:00), (Jim at 2014-10-10T09:01:00), (Jill at 2014-10-10T09:10:00), ...
The result set must contain the given User and Timestamp as well as the found room (if any).
------------------------------------------
| User | Timestamp | WasInRoom |
------------------------------------------
| Jim | 2014-10-09T09:05:00 | NULL |
| Jim | 2014-10-09T09:01:00 | A |
| Jim | 2014-10-10T09:10:00 | A |
The number of User-Timestamp tuples can be > 10 000.
The current implementation retrieves all records from Events table and does the search in Java code. I am hoping that I could push this logic to SQL. But how?
I am using MyBatis framework to create SQL queries so the tuples can be inlined to the query.
The basic query is:
select e.*
from events e
where e.user = 'Jim' and '2014-10-09T09:05:00' >= e.entered and ('2014-10-09T09:05:00' <= e.exited or e.exited is NULL) or
e.user = 'Jill' and '2014-10-10T09:10:00 >= e.entered and ('2014-10-10T09:10:00' <= e.exited or e.exited is NULL) or
. . .;
SQL Server can handle ridiculously large queries, so you can continue in this vein. However, if you have the name/time values in a table already (or it is the result of a query), then use a join:
select ut.*, t.*
from usertimes ut left join
events e
on e.user = ut.user and
ut.thetime >= et.entered and (ut.thetime <= exited or ut.exited is null);
Note the use of a left join here. It ensures that all the original rows are in the result set, even when there are no matches.
Answers from Jonas and Gordon got me on track, I think.
Here is query that seems to do the job:
CREATE TABLE #SEARCH_PARAMETERS(User VARCHAR(16), "Timestamp" DATETIME)
INSERT INTO #SEARCH_PARAMETERS(User, "Timestamp")
VALUES
('Jim', '2014-10-09T09:05:00'),
('Jim', '2014-10-10T09:01:00'),
('Jill', '2014-10-10T09:10:00')
SELECT #SEARCH_PARAMETERS.*, Events.Room FROM #SEARCH_PARAMETERS
LEFT JOIN Events
ON #SEARCH_PARAMETERS.User = Events.User AND
#SEARCH_PARAMETERS."Timestamp" > Events.Entered AND
(Events.Exited IS NULL OR Events.Exited > #SEARCH_PARAMETERS."Timestamp"
DROP TABLE #SEARCH_PARAMETERS
By declaring a table valued parameter type for the (user, timestamp) tuples, it should be simple to write a table valued user defined function which returns the desired result by joining the parameter table and the Events table. See http://msdn.microsoft.com/en-us/library/bb510489.aspx
Since you are using MyBatis it may be easier to just generate a table variable for the tuples inline in the query and join with that.
I have three tables with data like this:
An item table that contains basic info per item. Each item has one 'template' that determines a set of meta data for items with that template.
id | name | template_id
--------------------------
1 | Thing1 | t1
2 | Thing2 | t2
A template_fields table that contains a row for each type of meta data that could be associated with an item with particular template. It looks something like the table below. Here there are two templates, one with two fields and one with a single field. (The number of fields can vary per template.)
id | key | order
--------------------
t1 | color | 1
t1 | size | 2
t2 | year | 1
Finally, there is a meta_data table that contains the actual values associated with the template fields for each item:
item_id | template_id | key | value
--------------------------------------
1 | t1 | color | Red
1 | t1 | size | 2
2 | t2 | year | 2014
Now, in my application I want to have a per-template view of this data so that if I want to see items of template a particular template each row in the result set contains a column for each field in the corresponding template. For example, items in template t1 would look like this:
item_id | name | color | size
--------------------------------
1 | Thing1 | Red | 2
Similarly for items in template t2
item_id | name | year
------------------------
1 | Thing2 | 2014
Is there a way to do this in a single SQL query? (Keep in mind that I do not know the number of fields in a template until runtime. I am also not concerned with having a view that contains fields from items with different templates; one template at a time.)
My best whack at a solution so far is something like the pseudo code below, but please let me know if you think there is a better way (including a better table structure) to accomplish what I want.
fields = SELECT template_fields.key, meta_data.value FROM template_fields
JOIN meta_data ON
meta_data.template_id = template_fields.id
AND meta_data.key = template_fields.key
WHERE meta_data.item_id IN (SELECT id FROM item WHERE template='t1')
ORDER BY meta_data.item_id, template_fields.order
items = SELECT * FROM item WHERE template='t1'
i = 0
for item in items:
while fields[i].item_id = item.id:
item[fields[i].key] = fields[i].value
i += 1
Here's an SQL Fiddle link to play with