13

I am joining a large table in postgresql to a table with 1 row in it. Yes, I know I could just take the values from this single row table and put them in my query written out, but there's 210 columns.

So my question is this: should I join up the single row table to everything using a cross join or using a regular join on a tautology (1 = 1 or something). Is either of those ways bound to be slower?

Or is there a third faster way?

John
  • 321
  • 1
  • 3
  • 9
  • 1
    What exactly is the problem? You need to have all 210 columns in the join condition? – Marc B Jan 09 '14 at 19:54
  • 13
    Use `cross join` to make your intention clear. Otherwise next year you (or someone having to change your code) will wonder what that stupid `1=1` was supposed to mean. –  Jan 09 '14 at 19:54
  • 3
    Measure performance insted of asking for solution. – Mariusz Jamro Jan 09 '14 at 19:54
  • Why not use 2 queries if it's the same values for the 210 columns on every row? – dotjoe Jan 09 '14 at 19:54
  • As far as I have worked with, cross join is faster – Consult Yarla Jan 09 '14 at 19:54
  • @a_horse_with_no_name: You should make that an answer. – Ellesedil Jan 09 '14 at 20:01
  • Does this answer your question? [Correct way to select from two tables in SQL Server with no common field to join on](https://stackoverflow.com/questions/17582313/correct-way-to-select-from-two-tables-in-sql-server-with-no-common-field-to-join) – KyleMit Jan 09 '20 at 23:18

4 Answers4

11

One thing to note is a cross join will result in an empty table if one of the tables is empty. If one of your tables might be empty and you still want records, you may want an outer join (e.g. left, right, or full) on 1=1.

FistOfFury
  • 6,735
  • 7
  • 49
  • 57
4

The reason 1=1 exists is to make it easier to create dynamic sql statements by concatenating strings together (with the usual safeguards like parameterization, of course).

Having a predefined WHERE clause with 1=1 in it allows additional WHERE conditions to be added to the SQL without having to check for the existence of a WHERE clause first, and the SQL engine will generally optimize out the 1=1 so there's no performance difference.

In any other context, 1=1 is generally harmless, but not particularly useful.

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
1

They should perform and behave the same - the difference is in developer semantics

Here's a sample demo:

-- Setup
DECLARE @Codeset TABLE (id INT, [name] VARCHAR(50));
DECLARE @Student TABLE (id INT, [name] VARCHAR(50), age INT);

INSERT INTO @Codeset  
VALUES (1, 'HomeRoom');

INSERT INTO @Student  
VALUES (1, 'Jolly', 20), 
       (2, 'Sally', 22);

Let's say we want back every row from @Student and also to bring back the name value from @Codeset:

| id | name  | age | name     |
|----|-------|-----|----------|
| 1  | Jolly | 20  | HomeRoom |
| 2  | Sally | 22  | HomeRoom |

Any of the following syntaxes will accomplish this when either table has 0, 1, or 1+ records:

-- INNER JOIN 1=1
SELECT s.id, s.[name], s.age, c.[name]
FROM @Student s
INNER JOIN @Codeset c ON 1=1

-- Multiple From tables
SELECT s.id, s.[name], s.age, c.[name]
FROM @Student s,
     @Codeset c

-- CROSS JOIN
SELECT s.id, s.[name], s.age, c.[name]
FROM @Student s
CROSS JOIN @Codeset c

In this situation, you should prefer CROSS JOIN to be as explicit as possible as to your intentions to build a single select statement from multiple unrelated tables

Note: CROSS JOIN will output the same as INNER JOIN ON 1=1. Both produce the Cartesian product of all rows in both rowsets, so if one table is empty, the results will be as well.

If you need to guarantee results when @Students has records, but @Codeset might be empty, you will need to use LEFT JOIN ON 1=1

See Also: Correct way to select from two tables in SQL Server with no common field to join on

Community
  • 1
  • 1
KyleMit
  • 30,350
  • 66
  • 462
  • 664
-2

Based solely on my experience after writing huge amounts of sql. inner join on 1=1 is much faster than simply cross join.

Xinyu Li
  • 45
  • 5