How to display database records with <details> and <summary> - sql

I am trying use the HTML5 <details> and <summary> features to display records from my database. Example:
CATEGORY | TITLE
Fruit | Apple
Cars | Chevrolet
Actors | Tom Hanks
....
I would like to display the data like this:
Cars
Chevrolet
Ford
Vauxhall
Actors
Tom Hanks
Harrison Ford
Meryl Streep
Selina Gomez
How should the query and the display in HTML be constructed? I tried this query:
SELECT DISTINCT CATEGORY, TITLE
FROM TEST
GROUP BY CATEGORY
However, all I got from my works is something like this:
Actors
Tom Hanks
Actors
Harrison Ford
Do I need another query?

We use the cfquery, cfoutput containers to achieve this.
And the group parameter on cfoutput
And this is how it works:
<cfquery name='dataPuller' datasource='whateverYourDataSourceIs'>
SELECT DISTINCT CATEGORY, TITLE
FROM TEST
GROUP BY CATEGORY
ORDER BY CATEGORY
</cfquery>
<cfoutput query='dataPuller' group='category'>
<strong>#dataPuller.CATEGORY#</strong>
<br>
<li>
<cfoutput>
<ul>#dataPuller.TITLE#</ul>
</cfoutput>
</li>
</cfoutput>
Note the group parameter
Note the nested cfoutput
Hope this helps :)

Related

SQL Result to multiple array

MY SQL returns the following array...
id
staff
province
1
Ben
Ontario
2
Ben
Quebec
3
John
Manitoba
4
John
Saskatchewan
6
Kitty
Alberta
7
Kitty
Nova Scotia
I would like to have the record displayed like this...
staff
province
Ben
Ontario, Quebec
John
Quebec, Manitoba, Saskatchewan
Kitty
Alberta, Nova Scotia
what approach should I use to approach this?
Would be better to post the tables as well for clearer context.
You can use Aggregate functions and Grouping to help doing this. A GROUP BY to group the rows by staff column, then use GROUP_CONCAT() to concatenate province values in one string.
A reference of how you want it to be, unsure what table you are using or if there are any other factors but you can adapt as needed.
SELECT staff, GROUP_CONCAT(province SEPARATOR ', ') as province
FROM table_name
GROUP BY staff;

SQL selecting where A equals both B and C

name | course
Jay | LAWS0001
Mark | LAWS0002
Sam | LAWS0002
Alice | LAWS0001
Ryan | LAWS0001
Ryan | LAWS0002
Hey guys, I've got this database and I want to only select the names that take both 'LAWS0001' and 'LAWS0002'. So from this example, it should select 'Ryan' because he's the only person to take both courses.
I tried IN operator:
SELECT name
FROM student
WHERE course IN ('LAWS0001', 'LAWS0002')
but this takes everyone because everyone is taking either of the courses.
Is there an operator for my problem?
You can use your existing query, using a GROUP BY clause to COUNT the number of distinct courses each student is taking in the set ('LAWS0001', 'LAWS0002') and only selecting those students where the count is 2:
SELECT name
FROM student
WHERE course IN ('LAWS0001', 'LAWS0002')
GROUP BY name
HAVING COUNT(DISTINCT course) = 2
Demo on SQLFiddle

How would I match data in one column based on data from 2 or more columns

I'm having a bit of trouble trying to do this so if someone could point me in the right direction it would be greatly appreciated.
So the data in the excel file looks like so:
Work Title | Composers/Authors
------------------------------------------------------------------------------------
ACIDS ROCKS | BARLOW/FOSTER
ABOVE CLOUDS | JEFF BECK,CYNDI LAUPER,JED LEIBER
and the data in DB is similiar as in the authors could also be full names or just last names, but they are divided.
Now I would like to match that data with the data in the DB which for example looks like:
Work Title | Composers/Authors
------------------------------------------------------------------------------------
ACIDS ROCKS | DARREN JAMES BARLOW
ACIDS ROCKS | FOSTER
The desired outcome in this situation would be for these two works to match (value returned could be an ID that is tied to the title in the DB), but if the work doesn't for example contain the record with "FOSTER" then the two works shouldn't match.
The titles should match 100% (so if for example the title is THE ACIDS ROCKS it wouldn't match) and the authors should contain only the last name or it would probably be pretty tough to match them exact based on the data given.
Hope that this makes it clear.
EDIT:
After looking at the data some more and trying to compile it in such a way to be easier it should now look like so:
Data in DB
Work Title | Composers/Authors
------------------------------------------------------------------------------------
ACIDS ROCKS | DARREN JAMES BARLOW
ACIDS ROCKS | FOSTER
Data in excel table
Work Title | Composers/Authors
------------------------------------------------------------------------------------
ACIDS ROCKS | FOSTER
ACIDS ROCKS | DARREN JAMES BARLOW
So to make things simple I would only need the data to be 100% same so if the title matches (in this case ACIDS ROCKS) then the query should check if the authors are the same (in this case they are but not in the same order). I'm having problems with making it check every row individually.
The desired output here would be for the works to match since they have the same title and authors but if for example the DB data would look like
Work Title | Composers/Authors
------------------------------------------------------------------------------------
ACIDS ROCKS | DARREN JAMES BARLOW
ACIDS ROCKS | MARK FOSTER
then it shouldn't match. Even if FOSTER was missing or we have an additional author in the DB then it shouldn't match (not sure how tough it is to restrict this)
Run the following as is, if your Db2 is for Linux, Unix and Windows.
You may uncomment the commented out row and comment out the row above it to check the difference.
WITH
EXCEL_TABLE (Title, Author) AS
(
VALUES
('ACIDS ROCKS', 'FOSTER')
, ('ACIDS ROCKS', 'DARREN JAMES BARLOW')
)
, DB_TABLE (Title, Author) AS
(
VALUES
('ACIDS ROCKS', 'DARREN JAMES BARLOW')
, ('ACIDS ROCKS', 'FOSTER')
--, ('ACIDS ROCKS', 'MARK FOSTER')
)
SELECT E.Title, E.Authors
FROM
(
SELECT Title, LISTAGG(Author, ',') WITHIN GROUP (ORDER BY Author) AS Authors
FROM EXCEL_TABLE
GROUP BY Title
) E
JOIN
(
SELECT Title, LISTAGG(Author, ',') WITHIN GROUP (ORDER BY Author) AS Authors
FROM DB_TABLE
GROUP BY Title
) D ON D.Title = E.Title AND D.Authors = E.Authors;

query to search country name in text

I need a simple query that looks for a country in a text.
I have one table with different articles and on table with all the country names in the world.
ID | Article
1 | In China a three headed squid was sold to a bike vendor
2 | The government of Nigeria organised a slumber party
3 | Austria to ban australian comedians
CID | Name
1 | Nigeria
2 | Niger
3 | Austria
4 | China*
I only need the matches where the full country name appears in the article. I am currently using a 'like' query :
> Where a.Article like '%'||b.Name||'%'
but this way the article from NIGERIA is also matched to NIGER.
Any suggestions?
WHERE a.Article RLIKE "[[:<:]]b.Name[[:>:]]"
Try the above where clause
Here is a SQL fiddle, in which I select all the articles from the articles table, which are referring to Nigeria.
http://sqlfiddle.com/#!2/8b8c6/3
You can add a blank before and after the country name like this:
Where a.Article like '% '||b.Name||' %'
Not quite correct as you need to consider also that the country name is the first and the last word. So you will need also to check
Where a.Article like '%'||b.Name||' %'
and
Where a.Article like '% '||b.Name||'%'
Try this:!
SELECT * FROM tbl_article a WHERE (a.Article REGEXP ('EXACT VALUE'));

Multiple JOIN (SQL)

My problem is Play! Framework / JPA specific. But I think it's applicable to general SQL syntax.
Here is a sample query with a simple JOIN:
return Post.find(
"select distinct p from Post p join p.tags as t where t.name = ?", tag
).fetch();
It's simple and works well.
My question is: What if I want to JOIN on more values in the same table?
Example (Doesn't work. It's a pseudo-syntax I created):
return Post.find(
"select distinct p from Post p join p.tags1 as t, p.tags2 as u, p.tags3 as v where t.name = ?, u.name = ?, v.name = ?", tag1, tag2, tag3,
).fetch();
Your programming logic seems okay, but the SQL statement needs some work. Seems you're new to SQL, and as you pointed out, you don't seem to understand what a JOIN is.
You're trying to select data from 4 tables named POST, TAG1, TAG2, and TAG3.
I don't know what's in these tables, and it's hard to give sample SQL statements without that information. So, I'm going to make something up, just for the purposes of discussion. Let's say that table POST has 6 columns, and there's 8 rows of data in it.
P Fname Lname Country Color Headgear
- ----- ----- ------- ----- --------
1 Alex Andrews 1 1 0
2 Bob Barker 2 3 0
3 Chuck Conners 1 5 0
4 Don Duck 3 6 1
5 Ed Edwards 2 4 2
6 Frank Farkle 4 2 1
7 Geoff Good 1 1 0
8 Hank Howard 1 3 0
We'll say that TAG1, TAG2, and TAG3 are lookup tables, with only 2 columns each. Table TAG1 has 4 country codes:
C Name
- -------
1 USA
2 France
3 Germany
4 Spain
Table TAG2 has 6 Color codes:
C Name
- ------
1 Red
2 Orange
3 Yellow
4 Green
5 Blue
6 Violet
Table TAG3 has 4 Headgear codes:
C Name
- -------
0 None
1 Glasses
2 Hat
3 Monacle
Now, when you select data from these 4 tables, for P=6, you're trying to get something like this:
Fname Lname Country Color Headgear
----- ------ ------- ------ -------
Frank Farkle Spain Orange None
First thing, let's look at your WHERE clause:
where t.name = ?, u.name = ?, v.name = ?
Sorry, but using commas like this is a syntax error. Normally you only want to find data where all 3 conditions are true; you do this by using AND:
where t.name=? AND u.name=? AND v.name=?
Second, why are you joining tables together? Because you need more information. Table POST says that Frank's COUNTRY value is 4; table TAG1 says that 4 means Spain. So we need to "join" these tables together.
The ancient (before 1980, I think) way to join tables is to list more than one table name in the FROM clause, separated by commas. This gives us:
SELECT P.FNAME, P.LNAME, T.NAME As Country, U.NAME As Color, V.NAME As Headgear
FROM POST P, TAG1 T, TAG2 U, TAG3 V
The trouble with this query is that you're not telling it WHICH rows you want, or how they relate to each other. So the database generates something called a "Cartesian Product". It's extremely rare that you want a Cartesian Product - normally this is a HUGE MISTAKE. Even though your database only has 22 rows in it, this SELECT statement is going to return 768 rows of data:
Alex Andrews USA Red None
Alex Andrews USA Red Glasses
Alex Andrews USA Red Hat
Alex Andrews USA Red Monacle
Alex Andrews USA Orange None
Alex Andrews USA Orange Glasses
...
Hank Howard Spain Violet Monacle
That's right, it returns every possible combination of data from the 4 tables. Imagine for a second that the POST table eventually grows to 20000 rows, and the three TAG tables have 100 rows each. The whole database would be less than a megabyte, but the Cartesian Product would have 20,000,000,000 rows of data -- probably about 120 GB of data. Any database engine would choke on that.
So if you want to use the Ancient way of specifying tables, it is VERY IMPORTANT to make sure that your WHERE clause shows the relationship between every table you're querying. This makes a lot more sense:
SELECT P.FNAME, P.LNAME, T.NAME As Country, U.NAME As Color, V.NAME As Headgear
FROM POST P, TAG1 T, TAG2 U, TAG3 V
WHERE P.Country=T.C AND P.Color=U.C AND P.Headgear=V.C
This only returns 8 rows of data.
Using the Ancient way, it's easy to accidentally create Cartesian Products, which are almost always bad. So they revised SQL to make it harder to do. That's the JOIN keyword. Now, when you specify additional tables you can specify how they relate at the same time. The New Way is:
SELECT P.FNAME, P.LNAME, T.NAME As Country, U.NAME As Color, V.NAME As Headgear
FROM POST P
INNER JOIN TAG1 T ON P.Country=T.C
INNER JOIN TAG2 U ON P.Color=U.C
INNER JOIN TAG3 V ON P.Headgear=V.C
You can still use a WHERE clause, too.
SELECT P.FNAME, P.LNAME, T.NAME As Country, U.NAME As Color, V.NAME As Headgear
FROM POST P
INNER JOIN TAG1 T ON P.Country=T.C
INNER JOIN TAG2 U ON P.Color=U.C
INNER JOIN TAG3 V ON P.Headgear=V.C
WHERE P.P=?
If you call this and pass in the value 6, you get only one row back:
Fname Lname Country Color Headgear
----- ------ ------- ------ --------
Frank Farkle Spain Orange None
As was mentioned in the comments, you are looking for an ON clause.
SELECT * FROM TEST1
INNER JOIN TEST2 ON TEST1.A = TEST2.A AND TEST1.B = TEST2.B ...
See example usage of join here:
http://en.wikibooks.org/wiki/Java_Persistence/Relationships#Join_Fetching