Я презираю, когда вы принудительно присоединяете, используя WHERE
. Мне просто не нравится, грязный хак. Правильное соединение ANSI - использовать ON:
SELECT
p.Product,
o.Order
FROM
Product p
INNER JOIN
Order o
ON
o.OrderID = p.OrderID
Предпочтительно использовать ON
при подключении и WHERE
для фильтрации результатов. Помните, что ГДЕ - одна из последних вещей, которые вы будете использовать, помимо группировки и порядка, где вы хотите отфильтровать результаты. Таким образом, вы не должны присоединяться к своим таблицам с помощью WHERE
, поскольку его трудно прочитать.
SELECT
p.Product,
o.Order
FROM
Product p
INNER JOIN
Order o
ON
o.OrderID = p.OrderID
WHERE
o.Category = 'IT'
В конце концов, вы (разработчик), возможно, не будете в будущем, поэтому читаемость и ремонтопригодность будут помогите залить душу, которая должна взять ваш код:).
Когда я вижу, что разработчики используют WHERE
для объединения своих таблиц, это обычно указывает на то, что они не знают достаточно T-SQL. Это мое личное мнение.
Во-первых, синтаксис class << foo
открывает одноэлементный класс foo
(собственный класс). Это позволяет вам специализировать поведение методов, вызываемых для этого конкретного объекта.
a = 'foo'
class << a
def inspect
'"bar"'
end
end
a.inspect # => "bar"
a = 'foo' # new object, new singleton class
a.inspect # => "foo"
Теперь, чтобы ответить на вопрос: class << self
открывает одноэлементный класс self
, так что методы могут быть переопределены для текущего self
объект (который внутри тела класса или модуля является самим классом или модулем ). Обычно это используется для определения методов класса / модуля («статических»):
class String
class << self
def value_of obj
obj.to_s
end
end
end
String.value_of 42 # => "42"
Это также можно записать в сокращенном виде:
class String
def self.value_of obj
obj.to_s
end
end
Или даже короче:
def String.value_of obj
obj.to_s
end
Внутри определения функции self
относится к объекту, с которым вызывается функция. В этом случае class << self
открывает одноэлементный класс для этого объекта; одно из его применений - реализовать конечный автомат для бедняков:
class StateMachineExample
def process obj
process_hook obj
end
private
def process_state_1 obj
# ...
class << self
alias process_hook process_state_2
end
end
def process_state_2 obj
# ...
class << self
alias process_hook process_state_1
end
end
# Set up initial state
alias process_hook process_state_1
end
Итак, в приведенном выше примере каждый экземпляр StateMachineExample
имеет псевдоним process_hook
, связанный с process_state_1
, но обратите внимание, как в последнем случае он может переопределить process_hook
(только для self
, не затрагивая другие экземпляры StateMachineExample
) на process_state_2
. Таким образом, каждый раз, когда вызывающий абонент вызывает метод process
(который вызывает переопределяемый process_hook
), поведение изменяется в зависимости от того, в каком состоянии он находится.